JPA: When to choose Multivalued Association vs. Element Collection Mapping

*爱你&永不变心* 提交于 2019-11-28 17:48:55

Intuitively, I would typically use the @ElementCollection for composition scenarios. But even that feels very similar like CascadeType=DELETE

They are similar, with some slight differences. The ElementCollection page from the Java Persistence wikibook summarizes it pretty well:

Emdedded Collections

An ElementCollection mapping can be used to define a collection of Embeddable objects. This is not a typical usage of Embeddable objects as the objects are not embedded in the source object's table, but stored in a separate collection table. This is similar to a OneToMany, except the target object is an Embeddable instead of an Entity. This allows collections of simple objects to be easily defined, without requiring the simple objects to define an Id or ManyToOne inverse mapping. ElementCollection can also override the mappings, or table for their collection, so you can have multiple entities reference the same Embeddable class, but have each store their dependent objects in a separate table.

The limitations of using an ElementCollection instead of a OneToMany is that the target objects cannot be queried, persisted, merged independently of their parent object. They are strictly privately-owned (dependent) objects, the same as an Embedded mapping. Their is no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent. ElementCollection still can use a fetch type and defaults to LAZY the same as other collection mappings.

See also

Arthur Ronald

JPA specification is clear

Embeddables cannot be queried, persisted, merged independently of their parent object. They are strictly privately-owned (dependent) objects

You should use carefully because its lifespan is bounded by the lifespan of the owning entity instance. So if you persist/merge/remove your owning entity instance, all of its embeddables instances will be persisted/merged/removed

Suppose you do something like

/**
  * Let's suppose owning contains SIX embeddables instances
  */
Owning owning = manager.find(Owining.class, owningId);

So your modify just your Owning entity at view layer and submit your changes. You retrieve your Owning entity by using

/**
  * Usually your web framework Takes care of binding your submitted data
  */
Owning owning = new Owning();
owning.setProperty(request.getParameter("property"));

Then you can merge your submitted data and you Think your embeddables instances are stored in database yet. Well, let's see

As shown above you (or your web framework) just retrieved Owning properties, right ??? So your owning.getElementList() is empty. Because owning.getElementList() is empty, JPA will remove all of its embeddables instances. Keep this in mind.

Usually an embeddable class does not have relationship with other than its Owning Entity. And when using a Set of embeddables, JPA always select before saving/updating because it needs to compare one by one by using its equals method. So you need a consistent equals implementation when using a Set collection.

Here you can see its counterpart in Hibernate.

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