【问题标题】:Hibernate @ManyToOne Referenced Class using @NaturalId instead of @IdHibernate @ManyToOne 引用类使用@NaturalId 而不是@Id
【发布时间】:2015-11-07 21:32:42
【问题描述】:

我有一些 Hibernate/JPA 注释(老实说仍然不知道区别)允许我创建关联类。这个类将两个相关的项目组合成一个对象。我最初使用的是@JoinTable,但意识到我需要更多带有关联的元数据,因此不得不将代码转换为另一种对象类型。

现在我使用@Id 为我的对象标记ID 列,并使用@NaturalId (mutable = false) 标记String uuid

我的关联类正在使用 @ManyToOne 并可以很好地创建表,但是当我查看它时,表使用 @Id 字段作为映射列。我希望这个关联类使用@NaturalId uuid 以便于将关系/关联转移到其他系统。

我怎样才能让关系使用正确的标识符?

作为参考,我的数据库和 Java 代码如下所示:

AssociationsTable
----------------------------------------------
| ID | META DATA | ID ASSOC. 1 | ID ASSOC. 2 |
----------------------------------------------
| 1  |  stuff    |    1        |     2       |
----------------------------------------------

Objects
------------------------------
| ID | META DATA | UUID      | 
------------------------------
| 1  |  stuff    |  FOO-123  |
------------------------------
| 2  |  stuff    |  BAR-456  |
------------------------------

Association Class{
  ObjA main;
  ObjA sub;

  @ManyToOne
  getMain()

  @ManyToOne
  getSub()
}

ObjA Class{
  Long id;
  @Id
  @GeneratedValue(generator="increment")
  @GenericGenerator(name="increment", strategy = "increment")
  @XmlElement
  @Column(name = "ID", unique = true, nullable = false)
  getId()

  String uuid;    
  @NaturalId (mutable = false)
  @GeneratedValue(generator = "uuid")
  @GenericGenerator(name = "uuid", strategy = "uuid2")
  @Column(name = "uuid", unique = true)
  getUUID()
}

【问题讨论】:

  • 我知道your previous question。所以我决定澄清一下:你为什么担心链接表?我的意思是数据库级别的实体可以与@Id链接,然后它们可以用重置键值序列化,然后传输到其他实例,在java-bean级别用所有关系反序列化,然后用@的新值刷新到新数据库中987654332@ 属性...实体的主键会有所不同,但您仍将通过@NaturalId 字段获取它们。我错过了什么吗?..

标签: java hibernate jpa naturalid


【解决方案1】:

您可以使用@JoinColumnreferencedColumnName 属性,如here 所述。因此,对于您的示例,映射应如下所示:

ObjA.java:

package hello;

import org.hibernate.annotations.NaturalId;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class ObjA {
    Long id;
    String uuid;

    public ObjA() {
    }

    public ObjA(String uuid) {
        this.uuid = uuid;
    }

    @Id
    @GeneratedValue
    @Column(name = "obj_a_id", unique = true, nullable = false)
    Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @NaturalId(mutable = false)
    @Column(name = "uuid", unique = true, nullable = false)
    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }
}

Association.java:

package hello;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Association {
    Long id;
    ObjA main;
    ObjA sub;

    public Association() {
    }

    public Association(ObjA main, ObjA sub) {
        this.main = main;
        this.sub = sub;
    }

    @Id
    @GeneratedValue
    @Column(name = "association_id", unique = true, nullable = false)
    Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @ManyToOne
    @JoinColumn(name = "main_uuid", referencedColumnName = "uuid", nullable = false)
    public ObjA getMain() {
        return main;
    }

    public void setMain(ObjA main) {
        this.main = main;
    }

    @ManyToOne
    @JoinColumn(name = "sub_uuid", referencedColumnName = "uuid", nullable = false)
    public ObjA getSub() {
        return sub;
    }

    public void setSub(ObjA sub) {
        this.sub = sub;
    }
}

已成功测试这些映射以将来自obja 表的uuid 列的值存储在main_uuidsub_uuid 表的association 列中。这是使用 org.hibernate.common:hibernate-commons-annotations:4.0.5.Finalorg.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Finalorg.hibernate:hibernate-core:4.3.10.Finalorg.hibernate:hibernate-entitymanager:4.3.10.Final 针对 PostgreSQL 9.4.4 进行的测试。

【讨论】:

  • 我试过这个以及另外使用referencedTable,没有运气。
  • @Walls 我刚刚尝试在我的本地机器上使用referencedColumnName,它对我有用。我用我使用的确切映射更新了我的答案。如果您没有在关联表中看到 UUID,请确保您指向正确的数据库并且您也在重新生成它。
猜你喜欢
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
相关资源
最近更新 更多