我有以下代码来保存Oracle中的数据。
TRACE org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction - Adding resolved non-early insert action.
09-02-2018 15:14:54.273 TRACE org.hibernate.engine.internal.Cascade.cascade - Processing cascade ACTION_MERGE for: com.fis.cdpr.model.DataCollection
09-02-2018 15:14:54.273 TRACE org.hibernate.engine.internal.Cascade.cascade - Done processing cascade ACTION_MERGE for: com.fis.cdpr.model.DataCollection
09-02-2018 15:14:54.273 TRACE org.hibernate.engine.spi.CascadingAction.cascade - Cascading to merge: com.fis.cdpr.model.Language
09-02-2018 15:14:54.274 TRACE org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached - Merging detached instance
09-02-2018 15:14:54.274 TRACE org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad - Loading entity: [com.fis.cdpr.model.Language#06]
09-02-2018 15:14:54.274 TRACE org.hibernate.event.internal.DefaultLoadEventListener.doLoad - Attempting to resolve: [com.fis.cdpr.model.Language#06]
09-02-2018 15:14:54.274 TRACE org.hibernate.event.internal.DefaultLoadEventListener.doLoad - Resolved object in session cache: [com.fis.cdpr.model.Language#06]
09-02-2018 15:14:54.274 DEBUG org.hibernate.jpa.spi.AbstractEntityManagerImpl.markForRollbackOnly - Mark transaction for rollback
当我运行上面的代码时,它给我的事务回滚以下是日志
Language
我已经覆盖 Language lang1 = new Language();
lang1.setLangCode("06");
Language lang2 = new Language();
lang2.setLangCode("06");
em.merge(lang1);
em.merge(lang2);
对象
然后我尝试使用代码来检查问题并且它有效!!
09-02-2018 16:59:44.840 TRACE org.hibernate.engine.spi.ActionQueue.addInsertAction - Adding insert with no non-nullable, transient entities: [EntityInsertAction[com.fis.cdpr.model.Language#06]]
09-02-2018 16:59:44.840 TRACE org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction - Adding resolved non-early insert action.
09-02-2018 16:59:44.842 TRACE org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached - Merging detached instance
09-02-2018 16:59:44.842 TRACE org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad - Loading entity: [com.fis.cdpr.model.Language#06]
09-02-2018 16:59:44.843 TRACE org.hibernate.event.internal.DefaultLoadEventListener.doLoad - Attempting to resolve: [com.fis.cdpr.model.Language#06]
09-02-2018 16:59:44.843 TRACE org.hibernate.event.internal.DefaultLoadEventListener.doLoad - Resolved object in session cache: [com.fis.cdpr.model.Language#06]
09-02-2018 16:59:44.847 DEBUG org.hibernate.engine.transaction.internal.TransactionImpl.commit - committing
见下面的日志:
Data
我需要理解为什么从缓存中查看语言对象之后的hibernate不能持久保存相同的语言对象(diff引用)但能够持久保存相同的对象引用以及不同的语言对象
我在Document
和Language
的{{1}}上提供了关联,如下所示
@ManyToOne(cascade= CascadeType.ALL)
@JoinColumn(name = "language_fk")
private Language language;
更新=>例外说
exception [java.lang.IllegalStateException: Multiple representations of the same entity [spring.model.Language#06] are being merged. Detached: [spring.model.Language@b588a401]; Detached: [spring.model.Language@b588a401]]
文档课
@Entity
public class Document {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="doc_name", nullable=true)
private String name;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn
private Language lang;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn
private Data data;
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Language getLang() {
return lang;
}
public void setLang(Language lang) {
this.lang = lang;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((lang == null) ? 0 : lang.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Document other = (Document) obj;
if (id != other.id)
return false;
if (lang == null) {
if (other.lang != null)
return false;
} else if (!lang.equals(other.lang))
return false;
return true;
}
数据类
@Entity
public class Data {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="doc_name", nullable=true)
private String name;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="doc_fk")
private Document doc;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn
private Language lang;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Document getDoc() {
return doc;
}
public void setDoc(Document doc) {
this.doc = doc;
}
public Language getLang() {
return lang;
}
public void setLang(Language lang) {
this.lang = lang;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((lang == null) ? 0 : lang.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Data other = (Data) obj;
if (id != other.id)
return false;
if (lang == null) {
if (other.lang != null)
return false;
} else if (!lang.equals(other.lang))
return false;
return true;
}
}
}
语言课
@Entity
public class Language {
@Id
private String langCode;
private String language;
public String getLangCode() {
return langCode;
}
public void setLangCode(String langCode) {
this.langCode = langCode;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((langCode == null) ? 0 : langCode.hashCode());
result = prime * result + ((language == null) ? 0 : language.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Language other = (Language) obj;
if (langCode == null) {
if (other.langCode != null)
return false;
} else if (!langCode.equals(other.langCode))
return false;
if (language == null) {
if (other.language != null)
return false;
} else if (!language.equals(other.language))
return false;
return true;
}
}
从异常和我执行em.merge(lang)时; em.merge(lang2)我相信它有效,因为有两个单独的调用来持久化/合并数据,这就是为什么我这样做时从来没有异常。但除此之外它给出了例外。不是hibernate假设在Session中找到一个相同的对象时合并对象。 ?