我遇到了问题:我有一个实体定义,与DefinitionInfo实体有一个OneToMany关系,当我尝试加载现有的Definition时,向它的infoList集合添加一个DefinitionInfo,保存说它找不到我刚刚添加到Definition中的DefinitionInfo的实体。对此,我说' DUH!'我试图在定义中添加一个新的DefintionInfo,所以你当然找不到它!
以下是代码:
@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
目标/依赖对象:
Entity(name = "CohortGenerationInfo")
@Table(name="cohort_generation_info")
public class CohortGenerationInfo implements Serializable {
private static final long serialVersionUID = 1L;
public CohortGenerationInfo()
{
}
public CohortGenerationInfo(Integer cohortDefinitionId, Integer sourceId)
{
this.id = new CohortGenerationInfoPK(cohortDefinitionId, sourceId);
}
@EmbeddedId
private CohortGenerationInfoPK id;
@ManyToOne
@MapsId("cohortDefinitionId")
@JoinColumn(name="id")
private CohortDefinition cohortDefinition;
这是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)
我在堆栈跟踪的合并部分停了下来。它似乎是从数据库中获取现有实体并将其标记为mereg。定义已经存在,它只是一个新的DefinitionInfo被添加。
有没有人有任何想法?我对如何构建数据库有一些限制,但我希望这不是一个数据库结构问题,而只是一些令人讨厌的JPA。
答案 0 :(得分:2)
代码存在一些明显的问题。
@OneToMany(mappedBy="cohortDefinition", fetch= FetchType.LAZY, cascade= CascadeType.ALL)
currentDefinition.getGenerationInfoList().add(info); info.setCohortDefinition(currentDefinition);