2

チームには多くのプレーヤーがいるとします。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

うーん!

4

1 に答える 1

3

したがって、ここで間違っているのは、テーブルの結合とJPAタイプのORMがどのように機能するかについての私の理解でした(以前はMyBatisで作業していたので、まだJPAを学習しています)。直感的には、プレーヤーの配列リストを含むデータをチームクラスに追加して、それを永続化できると思うかもしれませんが、それはできません。最初にチームを永続化し、次にチームを各プレーヤーに順番に追加してから、一度に1人ずつ永続化する必要があります。したがって、本質的に、このコードには何の問題もありません。問題は椅子とコンピューターの間にありました。:/その後修正されました。

于 2012-05-12T05:51:15.253 に答える