Нужен пример сопоставления первичного ключа @OneToOne в Hibernate - PullRequest
5 голосов
/ 24 ноября 2008

Может кто-нибудь дать мне пример однонаправленного отображения первичного ключа @OneToOne в Hibernate? Я пробовал множество комбинаций, и пока лучшее, что я получил, это:

@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. Может кто-нибудь, пожалуйста, помогите мне? Если я не могу найти точное решение, подойдет что-то близкое, но я буду благодарен за любой ответ.

Ответы [ 5 ]

5 голосов
/ 24 ноября 2008

Я сохранил это обсуждение , когда я реализовал пару отображений @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;
    }
}
2 голосов
/ 24 ноября 2008

Ваше намерение состоит в том, чтобы иметь отношения 1-1 между PaperChequeStopMetaData и PaperCheque? Если это так, вы не можете определить экземпляр PaperCheque как @Id PaperChequeStopMetaData, вам нужно определить отдельный столбец @Id в PaperChequeStopMetaData.

1 голос
/ 31 августа 2017

Просто обновлю этот вопрос для будущих просмотров.

Когда этот вопрос был задан, я думаю, что не было правильного решения этой проблемы. Но начиная с JPA 2.0 вы можете использовать @MapsId для решения этой проблемы.

Ссылка с надлежащим объяснением: https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/

1 голос
/ 24 ноября 2008

Спасибо вам обоим за ваши ответы. Я продолжал экспериментировать, и вот что у меня получилось:

@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 раньше и согласился на гораздо худшие решения, но на этот раз я решил, что собираюсь выяснить, поэтому я продолжал хакать на это. Еще раз, спасибо вам обоим за ответы, это очень ценится.

0 голосов
/ 17 июня 2009

Вы должны держаться подальше от отображения OneToOne в hibernate, это очень опасно. см http://opensource.atlassian.com/projects/hibernate/browse/HHH-2128

Вам лучше использовать сопоставления ManyToOne.

...