2016-04-11 7 views
0

Hibernateは、そのアソシエーションのオブジェクトがコンポジットキーである場合、FKリファレンスを更新していないようです。ターゲットがコンポジットキーの場合、HibernateはManyToOneを保存しません

トランザクションは成功しますが(エラーもスタックトレースもありませんが)、更新ステートメントは生成されません(私は休止状態のロギングを有効にしています)。

私は、カスケード注釈(カスケード、ALL、PERSIST、さらにSAVE_UPDATEはありません)のすべてのやり方を試してみました。この更新のない症状は、OpenXavaのオンライン画面とカスタムJavaコードの両方から(OpenXavaアクション内に)存在します。

アプリケーションデータベースには、テーブルへの外部アップロードを許可する必要があるため、システムに割り当てられたキーに切り替えることは、彼らが追求するオプションではないと言われています。

(現在は任意のカスケード設定なし)所有協会:

@ManyToOne(fetch=FetchType.LAZY,optional=false) 
    @Required 
    @JoinColumns({ 
    @JoinColumn(name="programID",referencedColumnName="programID",nullable=false,unique=false,insertable=false,updatable=false), 
    @JoinColumn(name="projectID",referencedColumnName="projectID",nullable=false,unique=false,insertable=false,updatable=false) 
    }) 
    @DescriptionsList(descriptionProperties="parentProgram.programName,projectName") 
    @ReferenceView("reference") 
    private Project associatedProject; 

逆相関:

@OneToMany(mappedBy="associatedProject",fetch=FetchType.LAZY) //No cascade allowed 
    @ReadOnly 
    private Set<Asset> assets = new HashSet<Asset>(); 
オープンHibernateのバグがこの上がある場合

誰もが知っていますか?私はGoogleの検索を使用して見つけることができませんでしたが、おそらく誰かが最初の経験を持っています。

ありがとう、 Roy。

EDIT:回避策として、独自のHQLアップデートを作成しようとしました。 SET句を処理している間に鈍角Hibernateの構文エラーunexpected AST node: ANDに失敗し

update Asset set associatedProject = :ap where assetKey = :key 

update Asset cross join set projectID=?, programID=? where assetKey=?を生成して、自分のSQLの更新作業を行って、しかし「クロス」

で無効な構文で失敗しました

update Asset set associatedProject.projectId = :projId, associatedProject.parentProgram = :pgm where assetKey = :key 

誰かがより良い回避策を持っていますか?根本問題のさらなる考え方は?私の意見で

が、これはまだHibernateのバグを指す(もちろん、それはバグだ - あなただけ エラーやメッセージなし更新をスキップすることはできません)複合キーの取り扱いと。

+0

私はあなたのしたことをよく見ていませんが、休止状態のバグではないと考えています(休止状態は成熟しています)。 –

+0

@Robertは私の経験ではなく、そんなにありません。コンポジットキーのサポートのほとんどは、良く知られていませんし、広告されたものと正確には動作しません(ただし、ほとんどの問題の回避策があります)。 –

+0

@Brian 'programID/projectID'は、プロジェクトエンティティの複合キーです。 'programID'はプログラムエンティティのための単一のキーです。プログラムには多くのプロジェクトがあります。アセット(私の引用符で囲まれたコードのコンテキスト)は、特定のプロジェクト(Assetテーブルの2列FKとして実装されています)に関連付けられていますが、あるプロジェクトから別のプロジェクトに転送できます。これが症状の原因です - あるプロジェクトから別のプロジェクトへの関連付けを変更するとき、Hibernateは変更された 'associatedProject'値を保持しません。 –

答えて

0

Hibernateは、関係を保存しないと言っているので、関係を保存しません。 2つの@JoinColumnからinsertable = false、updatable = falseを削除するだけです。

+0

これは、繰り返される列について不平を言っているHibernateマッピング例外を生成するので、これは機能しません(上記のBrianへの私のコメントを参照してください)。さらに、Hibernateは、同じマッピング(これは、適切な複合キーFK参照サポートに必要とされる)上の真と偽のミックス&マッチを許しません。 –

+0

JPAでは、insertable = false、updatable = trueを指定しないで、同じ列に対してリレーションシップと列をマップすることはできません。あなたは、関係の設定者からプレーンプロパティを変更する必要があります。 OpenXavaTestプロジェクトのCarrier.javaを見てください – javierpaniza

0

ここでは、「派生アイデンティティー」を使用してプライマリキーをマッピングする方法について説明します。これが役立ちます。私はちょうどあなたのモデルを推測しています。しかし、これは始まりです....

@Entity 
public class Program { 
    @Id 
    int id; 

    @OneToMany(mappedBy="program") 
    Set<Project> projects; 

    ... 
} 

@Embeddable 
public class ProjectID { 
    int projectID; 
    int programID; // corresponds to the type of Program's primary key 

    ... 
} 

@Entity 
public class Project { 
    @EmbeddedId 
    ProjectID id; 

    @MapsId("programID") // maps 'programID' attribute of embedded ID 
    @ManyToOne 
    Program program; 

    @OneToMany(mappedBy="associatedProject", fetch=FetchType.LAZY) 
    Set<Asset> assets; 

    ... 
} 

@Embeddable 
public class AssetID { 
    int assetID; 
    ProjectID projectID; // corresponds to the type of Project's primary key 

    ... 
} 

@Entity 
public class Asset { 
    @EmbeddedId 
    AssetID id; 

    @MapsId("projectID") // maps 'projectID' attribute of embedded ID 
    @ManyToOne(fetch=FetchType.LAZY, optional=false) 
    Project associatedProject; 

    ... 
} 

派生したアイデンティティについては、JPA 2.1仕様2.4.1節で説明しています。

+0

OK、私は@EmbeddedIdパスを前に一回下りましたが、この議論のためにもう一度やり直しましょう。このモデルのいくつかの明確化 - プログラムとプロジェクトはそのままで良いです。しかし、Waveという3番目のレベルがあり、Projectの0:Mの直系子孫であり、複合キーはprogramID、projectID、WaveIDです。私の経験上、これはHibernateが複合キーの制限を第3レベルで表示し始めるところです。その後、Asset(キーは単なるassetID)には、FK to ProjectとオプションのFK to Waveがあります。 –

関連する問題