我有两个m:n关系的表。当我从数据库中提取数据时,这种关系应该是双向的,因此,我需要两个实体类中的@ManyToMany
。但是,与此同时,我需要非owner类在我对其执行持久化或合并操作时不插入所有者类。
例如,我有Gene
类,即所有者类,我有Ontology
类。 One Gene有许多Ontology,一个Ontology有很多基因。经典的多对多关系。如果我坚持或合并基因我也想插入它的Ontologies,但我不希望这个Ontology插入插入所有其他链接到它的基因。
另一方面,如果我插入一个Ontology,我不想插入与该Ontology相关的基因。
我一直在试用@ManyToMany
上的很多JPA标签,但没有任何方法可以按照我想要的方式进行。
有任何一个想法可以解决这个问题吗?
基因类
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = GeneTables.GENEINFO_HAS_ONTOLOGY,
joinColumns =
@JoinColumn(name = "GeneInfo_WID", referencedColumnName = "WID"),
inverseJoinColumns =
@JoinColumn(name = "Ontology_WID", referencedColumnName = "WID"))
private Set<Ontology> ontology;
Ontology类
@ManyToMany(cascade = CascadeType.REFRESH, mappedBy = "ontology")
private Set<GeneInfo> geneInfo;
我尝试了所有Cascade类型,甚至没有级联选项。结果是一样的。
执行此代码时出现此错误
EntityManager em = getEntityManager();
m.getTransaction().begin();
em.persist(ontology);
em.getTransaction().commit();
我有这个错误:
[EL Warning]: 2012-08-29 14:52:13.013--UnitOfWork(544628019)--java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
at org.jbiowh.core.datasets.ontology.controller.OntologyJpaController.create(OntologyJpaController.java:41)
at org.jbiowh.tools.prototypes.Test.main(Test.java:65)
解决了
我解决了这个问题。我创建了控制器类来处理特殊的级联。
Ontology控制器类上的create方法将是:
if (loadGeneFlag && ontology.getGene() != null && !ontology.getGene().isEmpty()) {
Set<Gene> geneSet = new HashSet<>();
GeneJpaController gController = new GeneJpaController(emf);
for (Gene gene : ontology.getGene()) {
Gene geneOnDB = em.find(Gene.class, gene.getWid());
if (geneOnDB != null) {
geneSet.add(geneOnDB);
} else {
gController.create(gene);
geneSet.add(em.getReference(Gene.class, gene.getWid()));
}
}
ontology.setGene(geneSet);
}
此代码将使用Gene控制器类创建所有基因引用,而不是遵循级联操作。这使我有可能在Gene控制器类上正确处理Gene级联。现在,我没有任何重复的对象,也没有例外。
答案 0 :(得分:1)
这些基因来自哪里?
如果它们是新的,那么你需要坚持它们,或者设置级联坚持基因关系。如果它们存在,那么您需要在当前EntityManager /事务的上下文中找到它们。
如果你不想那么坚持,那就不要把它们添加到基因集合中。
答案 1 :(得分:0)
在两个实体上设置 cascade = CascadeType.REFRESH 或删除两个实体上的级联属性。
答案 2 :(得分:0)
您必须在双向关系的一侧使用mappedBy。
请参阅, http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany#Bi-directional_Many_to_Many