jeudi 26 mai 2016

Hibernate update fails during test run with Spock, but succeeded in debug mode

Hibernate update fails during test run with Spock, but succeeded in debug
("Evaluate code fragment" mode).

ERROR: duplicate key value violates unique constraint "category_pkey" Detail: Key (id)=(1) already exists.

Latest libraries.

What is wrong?

How fix it?

class Test extends BaseSpecification {
private static final long one = 1L
private static final long two = 2L
private static final String name = "NAME"
private CategorySqlHibernateDAO target
@Shared
private Category firstCategory = new Category(id: one, name: name)
@Shared
private Category secondCategory = new Category(id: two, name: name, parent: firstCategory)

void setup() {
    add(firstCategory)
    target = getBean(CategorySqlHibernateDAO)
}

def "Save"() {// ---------------------- FAILED -----------------------------
    target.save(this.secondCategory)

    expect:
    assertTable(firstCategory, secondCategory)
}//...
}

BaseSpecification

abstract class BaseSpecification extends Specification {
protected Sql sql
protected final ApplicationContext context = new ClassPathXmlApplicationContext("contexts/dao-beans.xml")

protected initialize() {
    sql = new Sql(context.getBean(DataSource))
    truncate()
}

protected boolean truncate() {
    sql.execute("TRUNCATE TABLE " + modelClass.simpleName)
}

protected void add(Object... records) {
    initialize()
    if (specificationContext.currentIteration.name.toUpperCase().contains("SAVE")) {
         sql.dataSet(modelClass).add(ObjectUtility.asMap(records[0]))
    } else {
        records.each { sql.dataSet(modelClass).add(ObjectUtility.asMap(it)) }
    }
}

CategorySqlHibernateDAO

public class CategorySqlHibernateDAO extends HibernateDaoSupport {
@Transactional
public Serializable save(Entity entity) {
    return getHibernateTemplate().save(entity);
}
}

Category

@Entity
@Table(indexes = {
    @Index(name = "nameIndex", columnList = "name")})
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class Category implements NamedModel {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@NotNull
@Column(length = 256)
@Size(min = 1, max = 256)
private String name;
@JoinColumn(name = "parentId")
@OneToOne(fetch = FetchType.EAGER)
@JsonInclude(JsonInclude.Include.NON_NULL)
private Category parent;
@JsonIgnore
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@OneToMany(cascade = {CascadeType.REMOVE}, orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "parent")
private List<Category> children;
}

Aucun commentaire:

Enregistrer un commentaire