@ManyToOne (updatable=false) - как это должно работать?
Я хочу иметь доступную только для чтения функциональность в одной из моих сущностей. Я знаю, что в 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<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)
в сущности OrderedItem
, OrderedItem
будет извлечен из ПК, я получу доступ к его владельцу-a Customer
- и успешно изменил свое название. Это не было бы сюрпризом, потому что Customer
также был в управляемом состоянии, поэтому он должен был быть отражен в базе данных.
Однако , я предположил, что updateable=false
в @JoinColumn
, установленном на одной стороне отношения, предотвратит появление инструкции UPDATE SQL. К сожалению, в конце я вижу, что имя изменилось в базе данных (это "Терренс" вместо "Джон"). Я также могу видеть выполненный запрос обновления SQL:
[Эл Файн]: 2011-11-30 23:41:27.941--ClientSession(16862753)--связь(11024915)--резьба(резьба[основной,5,основным])--обновление ИМЯ НАБОРА КЛИЕНТОВ = ? ГДЕ (ID = ?) bind = > [Terrence, 1]
Итак, что же на самом деле делает этот updateable=false
? Зачем мне это нужно? Защищает ли он только мой внешний ключ от изменения? Это похоже на "вы не можете изменить сущность, но вы можете изменить состояние сущности"?