[英]How one to many relationship gets persisted in JPA if i have thousands of related entities already in data base and i add new entities in collection
We have two entities Entity1 and Entity2, where Entity1 contains set of Entity2, we already have thousands of entities stored in database of entity type Entity2 which all are referenced from an instance of Entity1, say myEntity. 我们有两个实体Entity1和Entity2,其中Entity1包含Entity2的集合,我们已经在实体类型Entity2的数据库中存储了成千上万个实体,所有这些实体都是从Entity1实例(例如myEntity)引用的。
Now if i add more Entity2 entities to the collection and try to persist myEntity, where newly added entities of Entity2 are already persisted. 现在,如果我将更多Entity2实体添加到集合中,并尝试保留myEntity,那么Entity2的新添加的实体已经存在。
My question is how will be the behavior on persist of myEntity , whether existing members of relation will travel to memory and new members will be added or new members are added to database without bringing existing members to memory 我的问题是,对myEntity进行持久化时的行为将如何,是关系的现有成员将移动到内存中,并且将新成员添加到数据库还是将新成员添加到数据库而不将现有成员带入内存
If you want to add new instances to a relation between two already existent entities (a one to many in this case) then you must first fetch from the database the entity that contains the collection; 如果要将新实例添加到两个已经存在的实体(在这种情况下是一对多)之间的关系中,则必须首先从数据库中获取包含集合的实体; in your case
myEntity
. 在您的情况下为
myEntity
。
So, when you load that entity you are bringing it to memory. 因此,当您加载该实体时,会将其带入内存。 If you had defined the relation between those two as
EAGER
then all the related entities (the ones in the collection) will be fetched as well at the same time than the parent one. 如果您将这两个实体之间的关系定义为
EAGER
则所有相关实体(集合中的实体)也将与父实体同时被获取。 If you, otherwise, had defined the relation as LAZY
then the related entities will be loaded when you access the collection (in other, words, when you invoke the getter getXXX
method for that collection). 如果您否则将关系定义为
LAZY
则在访问集合时(即,当您调用该集合的getter getXXX
方法时)将加载相关实体。
This happens that way because JPA implementations (now I'm thinking on Hibernate) return proxies of the entities instead of actual instances so they can intercept the getter/setter method calls and perform any tracking on the state of the entities. 之所以这样,是因为JPA实现(现在我正在考虑使用Hibernate)返回的是实体的代理,而不是实际的实例,因此它们可以拦截getter / setter方法调用并对实体的状态执行任何跟踪。
Right, so now you want to add more instances to the relation. 正确,所以现在您想向该关系添加更多实例。 It doesn't matter whether the relation is
EAGER
or LAZY
in this case as you will eventually invoking the getter method of the collection in order to be able to perform add(myNewEntity);
在这种情况下,关系是
EAGER
还是LAZY
都没有关系,因为您最终将调用该集合的getter方法,以便能够执行add(myNewEntity);
on it. 在上面。 So, the already existent entities are in the collection and you are just adding a (probably) untracked entity under the collection implementation semantics.
因此,已经存在的实体在集合中,而您只是在集合实现语义下添加了(可能)未跟踪的实体。
When persisting myEntity
back to the database the JPA implementation will know which instances of the actual collection need either an update
, a delete
or an insert
. 当将
myEntity
持久化回数据库时,JPA实现将知道实际集合的哪些实例需要update
, delete
或insert
。 If you just added new instances then just insert
statements will be issued but you could also remove an entity from the collection or change the state (invoke the setter) of an already existent instance. 如果您只是添加了新实例,则只会发出
insert
语句,但是您也可以从集合中删除实体或更改已经存在的实例的状态(调用设置器)。 JPA implementations are able to recognise those operations and issue the appropriate SQL statements to keep the database up to date. JPA实现能够识别这些操作并发出适当的SQL语句以使数据库保持最新状态。
If you have thousands of referenced entities, it might be better not to map the relationship and instead only query for it when needed - allowing you to use paging or other mechanisms to reduce the amount of entities read in at a time. 如果您有成千上万个引用的实体,最好不要映射该关系,而只在需要时查询它-允许您使用分页或其他机制来减少一次读入的实体数量。 It depends on what type of mapping it is, but only the owning relationship needs to be mapped (the one that doesn't have the mapped by) to set the foreign key in the database.
这取决于它是哪种映射类型,但是仅需要映射拥有关系(没有映射依据的关系)才能在数据库中设置外键。 Set the Entity2 side to be the owning side if it isn't already.
如果尚未将Entity2一方设置为拥有方,请设置它。
If this is a M:M with a relation table and doesn't make sense to map from the Entity2 side instead - you could add an entity for the relation table that you would read in the same way. 如果这是一个带有关系表的M:M,而不是从Entity2端进行映射,则可以为该关系表添加一个实体,该实体的读取方式相同。 The new entity would have a reference to Entity1, but Entity1 wouldn't reference it, and the app would query for the new entity when it needs to get Entity2s associated to a specific Entity1.
新实体将引用Entity1,但Entity1将不引用它,并且当需要获取与特定Entity1相关联的Entity2时,应用程序将查询新实体。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.