我想在我的一个实体中拥有只读功能.我知道在JPA 2.0中我们本身没有这样的功能.我认为我们可以使用updateable = false,insertable = false来实现它,但我认为我不知道它是如何工作的.
假设我有两个实体:OrderedItem和Customer:
@Entity
public class OrderedItem {
@Id
@GeneratedValue
private int id;
private String name;
@ManyToOne
@JoinColumn(updatable = false)
private Customer owner;
// bunch of simple getters and setters
}
@Entity
public class Customer {
@Id
@GeneratedValue
private int id;
private String name;
@OneToMany(mappedBy="owner")
private Set orderedItems;
// bunch of simple getters and setters
}
现在考虑以下代码:
Customer john = new Customer();
john.setName("John");
OrderedItem milk = new OrderedItem();
milk.setName("Milk");
milk.setOwner(john);
Set items = new HashSet();
items.add(milk);
john.setOrderedItems(items);
// This starts the EM transaction
startTx();
em.persist(john);
em.persist(milk);
stopTx();
startTx();
OrderedItem milkFromPC = em.find(OrderedItem.class, milk.getId());
System.out.println(milkFromPC.getName() + " ordered by customer: " +
milkFromPC.getOwner().getName());
// Changing the state of Owner entity through the OrderedItem
milkFromPC.getOwner().setName("Terrence");
stopTx();
现在,在OrderedItem实体中没有@JoinColumn(updatable = false),OrderedItem将从PC获取,我将访问它的所有者 – 客户 – 并且会成功修改其名称.这并不奇怪,因为客户也处于托管状态,因此必须反映在数据库中.
但是,我假设在关系的One侧设置的@JoinColumn中的updateable = false会阻止UPDATE SQL语句的发生.不幸的是,最后我可以看到数据库中的名称已更改(它是“Terrence”而不是“John”).我还可以看到执行的SQL UPDATE查询:
[EL Fine]: 2011-11-30
23:41:27.941–ClientSession(16862753)–Connection(11024915)–Thread(Thread[main,5,main])–UPDATE
CUSTOMER SET NAME = ? WHERE (ID = ?) bind => [Terrence, 1]
那么 – 这个updateable = false真的有用吗?我为什么需要它?它只保护我的外键不被改变吗?它是否像’你不能改变实体但你可以改变实体的状态’?