チームには多くのプレーヤーがいるとします。JPA/Hibernate の使用。ポストグル 9.1。GenerationType.IDENTITY (Postgres は Oracle のように int 列でシーケンスを使用します)。em.persist() の新しい挿入時に、子テーブルで null 以外のエラーが発生します (非常にわずかに難読化されたコードのプレーヤーテーブル...無実を保護するために名前が変更されました:) 以下のエラー情報.
親テーブル
@Entity
@Table(name = "team")
public class Team implements Serializable {
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
@Column(name = "teamid")
private Long teamid;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "teamid", fetch = FetchType.LAZY)
private Collection<Player> playerList;
子テーブル
@Entity
@Table(name = "player")
@XmlRootElement
public class Player implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "playerid")
private Long playerid;
@JoinColumn(name = "teamid", referencedColumnName = "teamid")
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Team teamid;
適切な測定のためのpersistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="ELS_Soulard_PU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/ElsDev1Pool</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
エラー情報:
INFO: THROWABLE INFO: org.postgresql.util.PSQLException: ERROR: null value in column "teamid" violates not-null constraint
INFO: Team Controller persistence exception THROWABLE MESSAGE: could not insert: [com.mydomainblahblahblah.persistence.entity.Player]
プレーヤーを方程式から外した場合、つまり「チーム」クラスでプレーヤー属性の値が null に設定されている場合 (プレーヤー リストを属性に追加するコードをコメントアウトしている場合)、データが正常に挿入されることに注意してください。チームテーブル。問題はすべてプレイヤーにあります。(Toronto Maple Leafs の所有者に聞いてみてください。:p)。
問題の原因は GenerationType.IDENTITY でしょうか? つまり、トランザクションが終了する前に親テーブルのチーム ID が返されないため、FK としてプレーヤー テーブルに配置できませんか? もしそうなら、別の世代タイプを使用する以外に、何か救済策はありますか? 私はデータベースシーケンスを使用するのが好きです(より多くの制御私見)。
シーケンス生成タイプの方が良いですか、それとも同じ問題ですか? しかし、これを行うには何らかの方法が必要であると確信しています。ありませんか?:/
ID を次のように変更しました (つまり、hibernate に ID を生成させます):
@Id
@Column(name = "teamid")
private Long teamid;
今、私はこのエラーが発生しています:
INFO: EXCEPTION CLASS NAME: javax.persistence.PersistenceException
INFO: THROWABLE CLASS NAME: org.hibernate.id.IdentifierGenerationException
うーん!