@ManyToOne(updatable=false) - how it should work?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-12 12:24:55

问题


I want to have a read-only functionality in one of my entities. I know that in JPA 2.0 we don't have such functionality per se. I thought we can achieve it using updateable=false, insertable=false but I don't think I get how it works.

Assume that I have two entities: OrderedItem and 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
}

Now consider the following code:

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();

Now, without @JoinColumn(updatable = false) in OrderedItem entity, the OrderedItem would be fetched from the PC, I'd access it's owner - a Customer - and would successfully modified its name. It wouldn't be a surprise because the Customer was also in managed state, so it had to be reflected in the database.

However, I assumed that updateable=false in @JoinColumn set on the One side of the relationship would prevent the UPDATE SQL statement from occurring. Unfortunately in the end I can see the name changed in the database (it's "Terrence" instead of "John"). I can also see the executed SQL UPDATE query:

[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]

So - what does this updateable=false really do? Why do I need it? Does it protect only my foreign key from being changed? Is it like 'you can't change the entity but you can change the state of the entity'?


回答1:


From the documentation

Whether the column is included in SQL UPDATE statements generated by the persistence provider.

So like you said, "it protects only my foreign key from being changed"



来源:https://stackoverflow.com/questions/8334216/manytooneupdatable-false-how-it-should-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!