Java JPA(Hibernate)问题保存多通关系
我遇到了一个问题:我有一个实体定义,它与DefinitionInfo实体有一个OneToMany关系,当我尝试加载一个现有定义时,将DefinitionInfo添加到它的信息列表集合中,Saved说它找不到我刚刚添加到定义中的DefinitionInfo的实体。对此,我说‘呸!’我正在尝试向定义中添加一个新的定义信息,因此您当然不会找到它 代码如下:Java JPA(Hibernate)问题保存多通关系,java,hibernate,jpa,Java,Hibernate,Jpa,我遇到了一个问题:我有一个实体定义,它与DefinitionInfo实体有一个OneToMany关系,当我尝试加载一个现有定义时,将DefinitionInfo添加到它的信息列表集合中,Saved说它找不到我刚刚添加到定义中的DefinitionInfo的实体。对此,我说‘呸!’我正在尝试向定义中添加一个新的定义信息,因此您当然不会找到它 代码如下: @Entity(name = "CohortDefinition") @Table(name="cohort_definition") @Name
@Entity(name = "CohortDefinition")
@Table(name="cohort_definition")
@NamedEntityGraph(
name = "CohortDefinition.withDetail",
attributeNodes = { @NamedAttributeNode(value = "details", subgraph = "detailsGraph") },
subgraphs = {@NamedSubgraph(name = "detailsGraph", type = CohortDefinitionDetails.class, attributeNodes = { @NamedAttributeNode(value="expression")})}
)
public class CohortDefinition implements Serializable{
private static final long serialVersionUID = 1L;
...
@OneToMany(mappedBy="cohortDefinition", fetch= FetchType.LAZY)
private Set<CohortGenerationInfo> generationInfoList;
...
+ Getters and Setters
这里是EmbeddedID类(信息的Id由定义的Id+表示不同类型信息的另一个实体的Id组成
@Embeddable
public class CohortGenerationInfoPK implements Serializable {
private static final long serialVersionUID = 1L;
public CohortGenerationInfoPK() {
}
public CohortGenerationInfoPK(Integer cohortDefinitionId, Integer sourceId) {
this.cohortDefinitionId = cohortDefinitionId;
this.sourceId = sourceId;
}
@Column(name = "id")
private Integer cohortDefinitionId;
@Column(name = "source_id")
private Integer sourceId;
+ getter/setter
这就是我正在做的。这应该很简单,但我不明白发生了什么:
Source source = this.getSourceRepository().findBySourceKey(sourceKey);
CohortDefinition currentDefinition = this.cohortDefinitionRepository.findOne(id);
CohortGenerationInfo info = findBySourceId(currentDefinition.getGenerationInfoList(), source.getSourceId());
if (info == null)
{
info = new CohortGenerationInfo(currentDefinition.getId(), source.getSourceId());
currentDefinition.getGenerationInfoList().add(info);
}
info.setStatus(GenerationStatus.PENDING)
.setStartTime(Calendar.getInstance().getTime());
this.cohortDefinitionRepository.save(currentDefinition);
下面是Hibernate选择,就在它爆炸之前:
Hibernate: select cohortgene0_.id as id1_4_0_, cohortgene0_.source_id as source_i2_4_0_, cohortgene0_.execution_duration as executio3_4_0_, cohortgene0_.is_valid as is_valid4_4_0_, cohortgene0_.start_time as start_ti5_4_0_, cohortgene0_.status as status6_4_0_, cohortdefi1_.id as id1_2_1_, cohortdefi1_.created_by as created_2_2_1_, cohortdefi1_.created_date as created_3_2_1_, cohortdefi1_.description as descript4_2_1_, cohortdefi1_.expression_type as expressi5_2_1_, cohortdefi1_.modified_by as modified6_2_1_, cohortdefi1_.modified_date as modified7_2_1_, cohortdefi1_.name as name8_2_1_ from cohort_generation_info cohortgene0_ inner join cohort_definition cohortdefi1_ on cohortgene0_.id=cohortdefi1_.id where cohortgene0_.id=? and cohortgene0_.source_id=?
以下是堆栈跟踪:
javax.persistence.EntityNotFoundException: Unable to find org.ohdsi.webapi.cohortdefinition.CohortGenerationInfo with id org.ohdsi.webapi.cohortdefinition.CohortGenerationInfoPK@3
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:183)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:989)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:716)
at org.hibernate.type.EntityType.resolve(EntityType.java:502)
at org.hibernate.type.EntityType.replace(EntityType.java:366)
at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:549)
at org.hibernate.type.CollectionType.replace(CollectionType.java:690)
at org.hibernate.type.TypeHelper.replace(TypeHelper.java:177)
at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:407)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:219)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:192)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
我停在堆栈跟踪的合并部分。它似乎是从DB和mereg中获取现有实体。定义确实存在,只是添加了一个新的定义信息
有人有什么想法吗?我对如何构造数据库有一些限制,但我希望这不是一个数据库结构问题,而只是JPA的一些恼人的问题。代码中有几个明显的问题
哇,你太棒了。一定是cascade=CascadeType.All。我没有info.setcoortdefinition,因为coortdefinitioninfo()将拥有它的队列定义和另一个存储库中查找值的PK的附加整数值带到其构造函数中。我没有为这个其他整数值建立关系,因为它不重要,但是coortDefinition.ID和这个其他实体ID都构成coortDefinitionInfo的PKntity(因此是复合键)。再次感谢您!
javax.persistence.EntityNotFoundException: Unable to find org.ohdsi.webapi.cohortdefinition.CohortGenerationInfo with id org.ohdsi.webapi.cohortdefinition.CohortGenerationInfoPK@3
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:183)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:989)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:716)
at org.hibernate.type.EntityType.resolve(EntityType.java:502)
at org.hibernate.type.EntityType.replace(EntityType.java:366)
at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:549)
at org.hibernate.type.CollectionType.replace(CollectionType.java:690)
at org.hibernate.type.TypeHelper.replace(TypeHelper.java:177)
at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:407)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:219)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:192)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
@OneToMany(mappedBy="cohortDefinition", fetch= FetchType.LAZY, cascade= CascadeType.ALL)
currentDefinition.getGenerationInfoList().add(info);
info.setCohortDefinition(currentDefinition);