5

Hibernate での一方向の @OneToOne 主キー マッピングの例を教えてください。私は数多くの組み合わせを試しましたが、これまでのところ私が得た最高のものはこれです:

@Entity
@Table(name = "paper_cheque_stop_metadata")
@org.hibernate.annotations.Entity(mutable = false)
public class PaperChequeStopMetadata implements Serializable, SecurityEventAware {

private static final long serialVersionUID = 1L;

@Id
@JoinColumn(name = "paper_cheque_id")
@OneToOne(cascade = {}, fetch = FetchType.EAGER, optional = false, targetEntity = PaperCheque.class)
private PaperCheque paperCheque;
}

Hibernate が上記のマッピングのスキーマを自動的に生成しようとするときはいつでも、PaperCheque の id タイプである long としてではなく、blob として主キーを作成しようとします。誰か助けてくれませんか?正確な解決策が得られない場合は、近いもので解決できますが、ご回答いただければ幸いです。

4

5 に答える 5

5

いくつかの @OneToOne マッピングを実装したときにこの議論を保存しました。皆さんにも役立つことを願っていますが、Hibernate にデータベースを作成させません。

GenericGenerator アノテーションに注意してください。

とにかく、私はこのコードが機能しています:

@Entity
@Table(name = "message")
public class Message implements java.io.Serializable
{
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "id", referencedColumnName = "message_id")
    public MessageContent getMessageContent()
    {
        return messageContent;
    }
}

@Entity
@Table(name = "message_content")
@GenericGenerator(name = "MessageContent", strategy = "foreign",
    parameters =
    {
      @org.hibernate.annotations.Parameter
      (
        name = "property", value = "message"
      )
    }
)
public class MessageContent implements java.io.Serializable
{
    @Id
    @Column(name = "message_id", unique = true, nullable = false)
    // See http://forum.hibernate.org/viewtopic.php?p=2381079
    @GeneratedValue(generator = "MessageContent")
    public Integer getMessageId()
    {
            return this.messageId;
    }
}
于 2008-11-24T16:24:06.917 に答える
2

あなたの意図は、PaperChequeStopMetaData と PaperCheque の間に 1 対 1 の関係を持つことですか? その場合、PaperCheque インスタンスを PaperChequeStopMetaData の @Id として定義することはできません。PaperChequeStopMetaData で別の @Id 列を定義する必要があります。

于 2008-11-24T16:24:33.437 に答える
1

お二方、ご回答ありがとうございます。私は実験を続けましたが、ここに私が得たものがあります:

@Entity
@Table(name = "paper_cheque_stop_metadata")
@org.hibernate.annotations.Entity(mutable = false)
public class PaperChequeStopMetadata implements Serializable, SecurityEventAware {

private static final long serialVersionUID = 1L;

@SuppressWarnings("unused")
@Id
@Column(name = "paper_cheque_id")
@AccessType("property")
private long    id;

@OneToOne(cascade = {}, fetch = FetchType.EAGER, optional = false, targetEntity = PaperCheque.class)
@PrimaryKeyJoinColumn(name = "paper_cheque_id")
@JoinColumn(name = "paper_cheque_id", insertable = true)
@NotNull
private PaperCheque paperCheque;

@XmlAttribute(namespace = XMLNS, name = "paper-cheque-id", required = true)
public final long getId() {
    return this.paperCheque.getId();
}

public final void setId(long id) {
    //this.id = id;
    //NOOP, this is essentially a pseudo-property
}
}

これは確かに嫌なハックですが、私が欲しかったものはすべて手に入れました. paperCheque プロパティ アクセサーは通常どおりです (表示されていません)。私は以前にこの種の一方向の OneToOne マッピングの問題に遭遇し、より悪い解決策に落ち着いたことがありますが、今回はそれを解明しようと決心したので、ハッキングを続けました。繰り返しになりますが、お二方の回答に感謝いたします。

于 2008-11-24T17:52:51.480 に答える
-2

hibernate の OneToOne マッピングには近づかないでください。非常に危険です。http://opensource.atlassian.com/projects/hibernate/browse/HHH-2128を参照してください。

ManyToOne マッピングを使用することをお勧めします。

于 2009-06-17T08:12:00.190 に答える