0

I have a one-to-many Category-Products relation:

public class **Category**{

    @Version
    private Integer version;

    @OneToMany(mappedBy = "category", cascade = {CascadeType.ALL})
    //@OptimisticLock(excluded = true)
    private List<Product> products
....

}

and the many-to-one side:

public class **Product**{

    @Version
    private Integer version;

    @ManyToOne
    @JoinColumn(name = "category_id")
    @ForeignKey(name = "fk_category_product")
    //@OptimisticLock(excluded = true)
    private Category category
....

}

I want to prevent Lost Modifications, so I defined a version mechanism (concurrency control) as above.

But when I want to save my parent entity(Category), I get the following error:

could not execute statement; SQL [n/a]; constraint [JOHN.SYS_C0090239]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

Here is my Action, service and dao layers:

Action

public String save() throws Exception {

        try {

            categoryManager.saveCategory(category);

        }catch (CategoryExistException e){
            List<Object> args = new ArrayList<Object>();
            args.add(category.getCategoryName());//categoryName is UNIQUE
            addActionError(getText("errors.existing.category", args));
            return INPUT;
        }

}

Manager

@Override
public Category saveCategory(Category category) throws CategoryExistException{

    if (category.getVersion()==null)
    {
        // if new category, lowercase categoryId
        category.setCategoryName(category.getCategoryName().toLowerCase());
    }

    try {
        return categoryDao.saveCategory(category);
    } catch (final Exception e) {
        e.printStackTrace();
        log.warn(e.getMessage());
        throw new CategoryExistException("Category '" + category.getCategoryName() + "' already exists!");
    }
}

Dao

@Override
public Category saveCategory(Category category){

    if (log.isDebugEnabled()) {
        log.debug("category's id: " + category.getCategoryId());
    }


    getSession().saveOrUpdate(category);
    //getSession().merge(category);

    // necessary to throw a DataIntegrityViolation and catch it in CategoryManger
    getSession().flush();


    return category;
}
Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
saeid
  • 1
  • 4

1 Answers1

0

Your problem is not related to optimistic locking. You get a ConstraintViolationException, due to the SQL JOHN.SYS_C0090239 constraint.

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
  • Hi vlad! I've tested without @version before and have'nt had any problem. – saeid Jan 15 '15 at 14:03
  • Constraint Type=Primary key , Search Condition=null – saeid Jan 15 '15 at 14:34
  • this is my Product's ID: @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQUENCE_GENERATOR) @SequenceGenerator(name = SEQUENCE_GENERATOR, allocationSize = 1, sequenceName = PRODUCT_SEQ) @Column(name = "product_id" , nullable = false) public Long getProductId() { return productId; } – saeid Jan 15 '15 at 14:42
  • Dear Vlad! I've set precisely both side references.but i'm wondering why getting error right after adding @version annotations ,while grasping the answer before... i don't know – saeid Jan 15 '15 at 15:00
  • do you think my action, service or dao are Correct? – saeid Jan 15 '15 at 15:11
  • Ok. One last thing. Try changing version from Integer to int. – Vlad Mihalcea Jan 15 '15 at 15:21
  • ichange Integer to int ,but getting this error: ORA-01400: cannot insert NULL into ("JOHN"."CATEGORY"."VERSION"). so why null? – saeid Jan 15 '15 at 15:28
  • @Version is using javax.persistence.* – saeid Jan 15 '15 at 15:35
  • (test-compile) Error on project John: Error executing database operation: CLEAN_INSERT: java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("AHMAD"."CATEGORY"."VERSION") -> [Help 1] – saeid Jan 15 '15 at 15:37
  • That's not Hibernate. That's DBUnit. You probably have a DBUnit xml file with some Categories that don't have a version, hence the null. – Vlad Mihalcea Jan 15 '15 at 15:47
  • Null value was assigned to a property of primitive type setter of net.sts.model.Category.version; nested exception is org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of net.sts.model.Category.version. – saeid Jan 15 '15 at 15:55
  • I have a sample-date.xml file which's populating the DB using DBUnit and have provided the following setting: category_idcategory_descriptioncategory_nameversion ,but never provided any value for version .Maybe that makes the problem?
    – saeid Jan 15 '15 at 16:00
  • Oh,Oh I'm sorry i'm getting the following error: Object of class [net.sts.model.Category] with identifier [3]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [net.sts.model.Category#3] – saeid Jan 15 '15 at 16:22