如何在我的类中拥有两个相同类型的对象?

3
我可以翻译以下内容:“我有一个需要拥有两个相同类型对象的类。我正在使用Hibernate,它会根据我的类创建数据库架构。”
“属性:”
private User user;
private User keyAccountManager;

Getter/Setter:

@ManyToOne
@JoinColumn(name = "userId")
@ForeignKey(name = "license_users_fk")
public User getUser() {
    return user;
}

@ManyToOne
@JoinColumn(name = "userId")
@ForeignKey(name = "license_kam_fk")
public User getKeyAccountManager() {
    return keyAccountManager;
}

如果我这样做,会出现以下错误:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: License column: userId (should be mapped with insert="false" update="false")
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:670)
    at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:692)
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:714)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:468)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:215)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1135)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1320)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
    ... 55 more

当我把它改成@JoinColumn(name = "userId", insertable=false, updatable=false)时,它可以顺利部署,列已在数据库中创建,但是当我调用setKeyAccountManager()时,值没有设置到数据库中。
在这个类中,我该如何拥有两个相同类型的对象?谢谢!
2个回答

3
问题并不是它们属于同一类。问题在于它们都映射到userId列。 Hibernate期望getKeyAccountManager()方法代表userId列或者getUser()方法代表userId列,但不是两个方法同时代表。 也许你引用了错误的列?

userId是用户类的ID。我还应该引用什么? - nimrod
这里的评论区有点小,无法详细解释注解的含义。简单来说,JoinColumn是注解所在类的表中列的名称。如果需要更多解释,我可以尝试澄清。 - Corbin
可以的!:)据我所知,它不是可以随意设置的 String 类型? - nimrod
需要等到明天才能得到完整的解释,但要点是userId属于带有@JoinColumn(name = "userId")注释的类,而不是User类。所以基本上,当你有两个@JoinColumn(name = "userId")时,你告诉Doctrine userId值映射到不同外键的两个不同项。一个列可以映射到多个内容,但一个列不能有多个映射。keyAccountManager是否始终等于用户?因为这就是你的注释所说的。 - Corbin
许可证始终引用创建许可证的用户。此外,许可证可以引用KAM。我认为这是我头脑中的逻辑问题,但我不知道如何解决它。 - nimrod
@corbin - 评论部分很小,因为它不是用来解释的。相反,您应该编辑您的答案以包含您的阐述。 - APC

2
假设需要有两个用户类型的类映射到名为License的表中。 @JoinColumnname属性定义了License表中具有外键约束的指向User表的列的名称。它绝对不是指向User表的主键,因为这些信息应该在User类本身上进行注释。
因此,在您的情况下,您应该使用不同的名称定义@JoinColumn,例如:
@ManyToOne
@JoinColumn(name = "user_Id")
@ForeignKey(name = "license_users_fk")
public User getUser() {
    return user;
}

@ManyToOne
@JoinColumn(name = "key_acct_mgr_id")
@ForeignKey(name = "license_kam_fk")
public User getKeyAccountManager() {
    return keyAccountManager;
}

那么,它被映射到以下表结构:
==================================================
| License                                        |
==================================================
|id (Primary key of table License)               |
|user_Id (Foreign key to the User Table)         |
|key_acct_mgr_id (Foreign key to the User Table) |
==================================================

谢谢你的答案。我试了一下,但表格没有更新 "key_acct_mgr_id"。有什么想法吗? - nimrod
你尝试将 hibernate.hbm2ddl.auto 设置为 update 并让 Hibernate 为你更新结构吗?之后,手动修正表格并删除不必要的内容。 - Ken Chan
是的,属性已经设置好了。今天早上重新启动计算机并清理数据库后,它终于可以工作了 :) 答案已被接受,非常感谢您的支持! - nimrod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接