Java 需要一个 Hibernate 中主键 @OneToOne 映射的例子
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/314578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Need an example of a primary-key @OneToOne mapping in Hibernate
提问by Alex Marshall
Can somebody please give me an example of a unidirectional @OneToOne primary-key mapping in Hibernate ? I've tried numerous combinations, and so far the best thing I've gotten is this :
有人可以给我一个在 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;
}
Whenever Hibernate tries to automatically generate the schema for the above mapping, it tries to create the primary key as a blob, instead of as a long, which is the id type of PaperCheque. Can somebody please help me ? If I can't get an exact solution, something close would do, but I'd appreciate any response.
每当 Hibernate 尝试为上述映射自动生成模式时,它都会尝试将主键创建为 blob,而不是 long,这是 PaperCheque 的 id 类型。有人能帮帮我吗 ?如果我不能得到一个确切的解决方案,可以做一些接近的事情,但我很感激任何回应。
采纳答案by David M. Karr
Your intention is to have a 1-1 relationship between PaperChequeStopMetaData and PaperCheque? If that's so, you can't define the PaperCheque instance as the @Id of PaperChequeStopMetaData, you have to define a separate @Id column in PaperChequeStopMetaData.
您的意图是在 PaperChequeStopMetaData 和 PaperCheque 之间建立 1-1 关系?如果是这样,则不能将 PaperCheque 实例定义为 PaperChequeStopMetaData 的 @Id,必须在 PaperChequeStopMetaData 中定义单独的 @Id 列。
回答by activout.se
I saved this discussionwhen I implemented a couple of @OneToOne mappings, I hope it can be of use to you too, but we don't let Hibernate create the database for us.
我在实现几个@OneToOne 映射时保存了这个讨论,我希望它对你也有用,但我们不让 Hibernate 为我们创建数据库。
Note the GenericGenerator annotation.
请注意 GenericGenerator 注释。
Anyway, I have this code working:
无论如何,我有这个代码工作:
@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;
}
}
回答by Alex Marshall
Thank you both for your answers. I kept experimenting, and here's what I got working :
谢谢你们的回答。我一直在试验,这就是我的工作:
@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
}
}
This is, by all means, a disgusting hack, but it gets me everything I wanted. The paperCheque property accessors are as normal (not shown). I've run into this kind of unidirectional OneToOne mapping problem before and settled for much worse solutions, but this time I decided I was going to figure out out, so I kept hacking away at it. Once again, thank you both for your answers, it's much appreciated.
无论如何,这是一个令人作呕的黑客行为,但它让我得到了我想要的一切。paperCheque 属性访问器是正常的(未显示)。我以前遇到过这种单向 OneToOne 映射问题,并解决了更糟糕的解决方案,但这次我决定要弄清楚,所以我一直在破解它。再次感谢两位的回答,非常感谢。
回答by Pat
You should stay away from hibernate's OneToOne mapping, it is very dangerous. see http://opensource.atlassian.com/projects/hibernate/browse/HHH-2128
你应该远离 hibernate 的 OneToOne 映射,它是非常危险的。见http://opensource.atlassian.com/projects/hibernate/browse/HHH-2128
you are better off using ManyToOne mappings.
最好使用多对一映射。
回答by ítalo Vieira
Just updating this question for future views.
只是更新这个问题以供将来查看。
When this question was made i think there wasn't a proper solution for this problem. But since JPA 2.0 you can use @MapsId to solve this problem.
当提出这个问题时,我认为这个问题没有合适的解决方案。但是从 JPA 2.0 开始,你可以使用 @MapsId 来解决这个问题。
Reference with proper explanation: https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/
参考适当的解释:https: //vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/