According to the JPA 2.0 specification:
The version attribute is updated by the persistence provider runtime when the object is written to the database. All non-relationship fields and properties and all relationships owned by the entity are included in version checks.
This doesn't seem to work in my case. I have two Entities:
@Entity
public class OrderedItem {
@Id
@GeneratedValue
private int id;
private String name;
@ManyToOne
private Customer owner;
@Version
private int version;
public OrderedItem(String name) {
this.name = name;
}
// default constructor + bunch of simple accessors and mutators
}
@Entity
public class Customer {
@Id
@GeneratedValue
private int id;
private String name;
@OneToMany(mappedBy = "owner")
private Set<OrderedItem> orderedItems = new HashSet<OrderedItem>();;
@Version
private int version;
public Customer(String name) {
this.name = name;
}
// default constructor + bunch of simple accessors and mutators
}
The "many" side of ManyToOne
relationship must be an owning side, so in my case the OrderedItem
is the owning side. Following the JPA 2.0 spec, I assume that when I change the Customer
object accessed from OrderedItem
the version of OrderedItem
entity should be incremented. Therefore, I've tried to test it:
Customer john = new Customer("John");
OrderedItem milk = new OrderedItem("Milk");
milk.setOwner(john);
john.getOrderedItems().add(milk);
startTx();
em.persist(john);
em.persist(milk);
stopTx();
startTx();
OrderedItem milkFromPC = em.find(OrderedItem.class, milk.getId());
milkFromPC.getOwner().setName("Michael");
stopTx();
The version numbers are 1 for OrderedItem
(so no increment) and 2 for Customer
.
Any ideas why?
It just bumped into my head while writing this question - is it possible that the "relationship" word in JPA 2.0 specification means that only if I change the entity -- Customer
-- itself (not its state) the version will be incremented? Just like in case of @JoinColumn(updatable=false)
?
Yes, as I understand it the version field of OrderedItem will change, if you reassign a different Customer, but not if you change a property of the customer.
On the other hand, if you add another OrderedItem to the OrderedItem set of the Customer, the version field of the Customer doesn't get updated because it's not the owning side.
I guess it's useful here to think here in table rows: if any column in a table row changes the version column of that table row gets incremented.
It's fine if one client updates the name of the OrderedItem and another the name of the Customer - these updates don't conflict.