Если у меня есть двунаправленная связь в моей DataModel, то моя заявка несет ответственность за обновление ссылок в Java-коде.JPA двунаправленные отношения
Каков наилучший способ для этого?
Например, бидир. 1: N соотношение между А и В.
@Entity
class A {
@ManyToOne
private B b;
}
@Entity
class B {
@OneToMany(mappedBy="b")
private Collection<A> as;
}
Если я скажу B.addA (б) это не позволяет переменной Ь в точке к опорному я добавил. И если я вызываю A.setB (b), это не добавляет ссылку на b в коллекцию в B.
Одним из возможных способов было бы вызвать setB AND addA в моем коде приложения.
Другой вешать было бы написать метод множество А (..), как это:
public setB(B b) {
this.b = b;
if(!b.contains(this) {
b.add(this);
}
}
public addA(A a) {
if(!as.conatains(a)) {
as.add(a);
}
a.setB(this);
}
но иногда бросает некоторые исключения, как:
org.hibernate.LazyInitializationException: illegal access to loading collection
я думаю, потому что структура вызовов в somepoint this setMethod и хотите загрузить «эту» ссылку ...?!? может кто-нибудь объяснить мне, почему это происходит? И каков путь, чтобы гарантировать, что у меня есть чистые взаимозависимые отношения в моем java-коде?
ТНХ
UPDATE: здесь исходный код:
@Entity
class Cluster{
private Grid grid
//someother fields
@ManyToOne
public Grid getGrid() {
return grid;
}
public void setGrid(Grid grid) {
this.grid = grid;
if(!grid.getClusters().contains(this)) { //HERE AN EXCEPTION IS THROWN
grid.addCluster(this);
}
}
}
@Entity
class Grid {
private Collection<Cluster> clusters = new ArrayList<Cluster>();
//some other fields
@OneToMany(mappedBy = "grid", cascade = CascadeType.PERSIST, orphanRemoval = true)
public Collection<Cluster> getClusters() {
return clusters;
}
public void setClusters(Collection<Cluster> clusters) {
this.clusters = clusters;
}
public void addCluster(Cluster c) {
this.clusters.add(c);
c.setGrid(this);
}
}
В одном из моих запросов я получаю исключение, которое говорит, что что-то внутри ист setGrid метод неправильно ... Если я удаляю линии, все в порядке .. но тогда у меня нет моей двунаправленной ...:/
Стекло:
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: Exception occurred inside setter of dst1.model.Cluster.grid
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1214)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:255)
at dst1.Main.dst02b(Main.java:828)
at dst1.Main.main(Main.java:38)
Caused by: org.hibernate.PropertyAccessException: Exception occurred inside setter of dst1.model.Cluster.grid
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:89)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:583)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:229)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3822)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:152)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
at org.hibernate.loader.Loader.doQuery(Loader.java:857)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2037)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3268)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:496)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:477)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:285)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:1038)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:630)
at org.hibernate.type.EntityType.resolve(EntityType.java:438)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
at org.hibernate.loader.Loader.doQuery(Loader.java:857)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.doList(Loader.java:2533)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
at org.hibernate.loader.Loader.list(Loader.java:2271)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:246)
... 2 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:66)
... 35 more
Caused by: org.hibernate.PropertyAccessException: Exception occurred inside setter of dst1.model.Cluster.grid
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:89)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:583)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:229)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3822)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:152)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
at org.hibernate.loader.Loader.doQuery(Loader.java:857)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2166)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:62)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:627)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1863)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:369)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.AbstractPersistentCollection.readElementExistence(AbstractPersistentCollection.java:167)
at org.hibernate.collection.PersistentBag.contains(PersistentBag.java:262)
at dst1.model.Cluster.setGrid(Cluster.java:114)
... 40 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:66)
... 57 more
Caused by: org.hibernate.LazyInitializationException: illegal access to loading collection
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:366)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.AbstractPersistentCollection.readElementExistence(AbstractPersistentCollection.java:167)
at org.hibernate.collection.PersistentBag.contains(PersistentBag.java:262)
at dst1.model.Cluster.setGrid(Cluster.java:114)
... 62 more
У вас еще нет ни одного отзыва? –
Привет и большое спасибо за вашу помощь, но, к сожалению, это не решило проблему. Всякий раз, когда я хочу получить коллекцию другого объекта из метода set/add связанного объекта, я получаю это LazyInitializationException:/Я попытаюсь разобрать свое решение и посмотреть, могу ли я получить более подробную информацию о том, почему это происходит :(thank вы за вашу помощь – Moonlit
Возможно, вам стоит задать вопрос на форуме Hibernate, они будут лучше знать внутренности реализации. –