@ManyToOne(updatable = false) - 它应该如何工作?

时间:2011-11-30 22:57:00

标签: java jpa-2.0 eclipselink java-ee-6 readonly

我希望在我的某个实体中拥有只读功能。我知道在JPA 2.0中我们本身没有这样的功能。我认为我们可以使用updateable=false, insertable=false来实现它,但我认为我不知道它是如何工作的。

假设我有两个实体:OrderedItemCustomer

@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<OrderedItem> 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<OrderedItem> items = new HashSet<OrderedItem>();
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();

现在,在@JoinColumn(updatable = false)实体中没有OrderedItemOrderedItem将从PC获取,我将访问它的所有者 - Customer - 并且会成功修改其名称。这并不奇怪,因为Customer也处于托管状态,因此必须反映在数据库中。

但是,我假设关系One侧的updateable=false中的@JoinColumn会阻止UPDATE SQL语句的发生。不幸的是最后我可以看到数据库中的名称发生了变化(它是“Terrence”而不是“John”)。我还可以看到执行的SQL UPDATE查询:

  

[EL精]:2011-11-30   23:41:27.941 - ClientSession的(16862753) - 连接(11024915) - 线程(线程[主,5,主]) - UPDATE   CUSTOMER SET NAME =? WHERE(ID =?)bind =&gt; [泰伦斯,1]

那么 - updateable=false真正做到了什么?我为什么需要它?它只保护我的外键不被改变吗?它是否像'你不能改变实体但你可以改变实体的状态'?

1 个答案:

答案 0 :(得分:3)

来自documentation

  

该列是否包含在由持久性提供程序生成的SQL UPDATE语句中。

就像你说的那样,“它只保护我的外键不被改变”