@ManyToOne (updatable = false) - как это должно работать? - PullRequest
4 голосов
/ 01 декабря 2011

Я хочу иметь функцию только для чтения в одном из моих объектов. Я знаю, что в 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 будет получен с ПК, я получу доступ к его владельцу - Customer - и успешно изменит его имя. Это не будет сюрпризом, поскольку Customer также находится в управляемом состоянии, поэтому его необходимо отразить в базе данных.

Однако , я предположил, что updateable=false в @JoinColumn, установленном на одной стороне отношения, предотвратит выполнение оператора UPDATE SQL. К сожалению, в итоге я вижу измененное имя в базе данных (это «Терренс» вместо «Джон»). Я также вижу выполненный запрос SQL UPDATE:

[EL Fine]: 2011-11-30 23: 41: 27,941 - ClientSession (16862753) - Соединение (11024915) - нить (резьба [основное, 5, главный]) - ОБНОВЛЕНИЕ ИМЯ ЗАКАЗЧИКА =? ГДЕ (ID =?) Bind => [Терренс, 1]

Итак - что это на самом деле делает updateable=false? Зачем мне это нужно? Защищает ли он только мой внешний ключ от изменения? Это как «вы не можете изменить сущность, но вы можете изменить состояние сущности»?

1 Ответ

3 голосов
/ 01 декабря 2011

Из документации

Включен ли столбец в операторы SQL UPDATE, сгенерированные поставщиком сохраняемости.

Итак, как вы сказали, «он защищает только мой внешний ключ от изменения»

...