如果有一個JEE6應用程序可以在Glassfish 3.1.1上運行良好,這是多年以來的事情。現在必須把它移到JEE7/Glassfish的4.1.1,撞上了幾個問題就JPA/EclipseLink的:JPA 2.1單向OneToMany映射:EDITED
一)我有一個實體申請人包含映射爲單向一對多關係幾列。
@Entity
@Table(name="applicant")
@AttributeOverride(name="id", [email protected](name="UserID", insertable=false, updatable=false))
public class Applicant extends BaseEntityVersioned implements Serializable {
..
..
@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)
@JoinColumn(name="BewerberID", nullable=false)
private List<ITKenntnis> itKenntnisse = new ArrayList<ITKenntnis>();
..
public List<ITKenntnis> getITKenntnisse() {
return this.itKenntnisse;
}
public void setITKenntnisse(List<ITKenntnis> itKenntnisse) {
this.itKenntnisse = itKenntnisse;
}
public ITKenntnis createITKenntnis(){
return new ITKenntnis();
}
public boolean addITKenntnis(ITKenntnis itKenntnis) {
getITKenntnisse().add(itKenntnis);
return true;
}
...
}
與實體ITKEnntnis
@Entity
@Table(name="ITKenntnis")
public class ITKenntnis extends BaseEntityVersioned implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Integer id;
@Override
public Integer getId() {
return id;
}
@Override
public void setId(Integer id) {
this.id=id;
}
}
直到現在我只是增加ITKentnis的新實例申請人與addKenntnis並堅持申請人。 在GlassFish 4.1.1我得到一個錯誤 - >
javax.persistence.PersistenceException:異常[的EclipseLink-4002](Eclipse持久服務 - 2.6.2.qualifier):org.eclipse.persistence.exceptions.DatabaseException 內部異常:java.sql.SQLException中:字段「BewerberID」沒有默認值 錯誤代碼:1364
字段「BewerberID」在我的數據庫表的外鍵不能爲空,我無法改變這個定義。
到目前爲止,我發現的唯一解決方法是將關係重新定義爲雙向。由於我有很多關係,並且代碼與JPA 2.0一起工作,如果有更簡單的解決方案,我將不勝感激。
b)我有一個實體應用程序,它定義了與申請人的單向@ ManyToOne關係。
@Entity
@Table(name="bewerbungen")
public class Application extends BaseEntityVersioned implements Serializable {
...
// uni-directional
@ManyToOne (fetch=FetchType.LAZY)
@JoinColumn(name="BewerberID")
private Bewerberprofil bewerberprofil;
...
}
無論閹這是一個很好的設計或沒有(我的理由來映射這種方式) - >當我嘗試刪除我看到那臺場「BewerberID」爲null更新的實體,而不是刪除。爲什麼在JPA 2.1中,我該如何改變它?
對不起,很長的文章。
托馬斯
編輯: 我進行了進一步研究這些問題,調試對Glasfish 3.1.1生成的SQL語句。服務器正在工作。
添加新的子實體有哪些是一樣的新服務器上下面的SQL語句 - 新服務器上的INSERT失敗,因爲該領域「BewerberID」>
[#|2016-04-26T17:22:55.613+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=25;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:22:55.613--ClientSession(1645443748)--Connection(1826150217)--Thread(Thread[http-thread-pool-80(2),5,grizzly-kernel])--INSERT INTO bewerberedv (Bearbeitet, Bereich, Bewertung, Dauer, Kenntnis, Version, ZuletztVerwendet) VALUES (?, ?, ?, ?, ?, ?, ?)
bind => [true, 6, 1, null, 377, 2016-04-26 17:24:08.0, null]
|#]
[#|2016-04-26T17:22:55.628+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=25;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:22:55.628--ClientSession(1645443748)--Connection(1826150217)--Thread(Thread[http-thread-pool-80(2),5,grizzly-kernel])--SELECT LAST_INSERT_ID()
|#]
[#|2016-04-26T17:22:55.644+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=25;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:22:55.644--ClientSession(1645443748)--Connection(1826150217)--Thread(Thread[http-thread-pool-80(2),5,grizzly-kernel])--UPDATE bewerberedv SET BewerberID = ? WHERE (ID = ?)
bind => [2575, 1223970]
|#]
不同的是,不能爲NULL。不知何故,數據庫中的檢查似乎有所不同。
同樣對於刪除的有以下輸出 - >
[#|2016-04-26T17:13:39.363+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=31;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:13:39.363--ClientSession(792940001)--Connection(1806567172)--Thread(Thread[http-thread-pool-80(4),5,grizzly-kernel])--UPDATE bewerbungen SET BewerberID = ?, PositionID = ?, InseratID = ?, Version = ? WHERE ((ID = ?) AND (Version = ?))
bind => [null, null, null, 2016-04-26 17:14:52.0, 1304157, 2016-04-26 17:14:25.0]
|#]
[#|2016-04-26T17:13:39.363+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=31;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:13:39.363--ClientSession(792940001)--Connection(1806567172)--Thread(Thread[http-thread-pool-80(4),5,grizzly-kernel])--UPDATE inserateanz SET AnzahlBew = ?, AnzOffeneBewerbung = ?, AnzNeueBewerbung = ? WHERE (ID = ?)
bind => [0, 0, 0, 61277]
|#]
[#|2016-04-26T17:13:39.363+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=31;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:13:39.363--ClientSession(792940001)--Connection(1806567172)--Thread(Thread[http-thread-pool-80(4),5,grizzly-kernel])--UPDATE positionenanz SET AnzahlBew = ?, AnzOffeneBewerbung = ?, AnzNeueBewerbung = ? WHERE (ID = ?)
bind => [0, 0, 0, 44726]
|#]
[#|2016-04-26T17:13:39.363+0200|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=31;_ThreadName=Thread-2;|[EL Fine]: 2016-04-26 17:13:39.363--ClientSession(792940001)--Connection(1806567172)--Thread(Thread[http-thread-pool-80(4),5,grizzly-kernel])--DELETE FROM bewerbungen WHERE ((ID = ?) AND (Version = ?))
bind => [1304157, 2016-04-26 17:14:52.0]
那interresting因爲新的服務器我有同樣的更新語句 「?UPDATE bewerbungen SET BewerberID = ....」 上,但在那裏它立即失效,並帶有空限制!
Unidirectional OneToMany關係使用連接表。你是否暗示你之前沒有這樣做?請參閱JPA規範(2.0或2.1)的§2.10.5.1 –
是的,它自2011年起使用JPA2.0。還請查看高級下的https://en.wikibooks.org/wiki/Java_Persistence/OneToMany。 –
另請參見Mike Keith章節「高級對象關係映射」中的「Pro JPA 2」:避免連接表 到目前爲止,我們已經討論了使用連接表的上下文中的單向一對多映射,但它是 也可能映射單向映射而不使用連接表。它要求外鍵位於目標 表或關係的「多」一側,即使目標對象沒有任何對「one」一方的引用。 這被稱爲單向一對多目標外鍵映射,因爲外鍵在目標表 而不是...... –