Eclipse hibernate pojo生成包括外键

时间:2015-12-15 23:49:33

标签: java eclipse hibernate foreign-keys hibernate-tools

我一直在关注使用hibernate从mysql数据库生成pojos的优秀指南。可以在这里找到指南供参考: Generate pojos with hibernate

我得到pojos,当外键存在时,其中包含嵌入其他对象的字段。例如,用户有地址。 Hibernate产生如下内容:

public class User(){
 private String name;
 private Integer uid;
 private Address address;
}

我有一个问题,因为我希望这些类实际包含外键值。例如,我希望User对象具有与addressId的数据库字段对应的类字段。所以,我希望对象看起来像这样:

public class User(){
 private String name;
 private Integer uid;
 private Integer addressId;
 private Address address;
}

有没有人知道如何修改hibernate代码生成过程,以便将外键值包含在对象的字段中?

更新 我发现了一篇SO帖子,它描述了如何忽略外键关系,只是将外键作为类字段:How to ignore foreign keys?

这里的问题是我想要两者。我不想忽视这种关系。我希望它们代表,但我也想要实际的外键值。

更新

让我更具体地说明为什么我想要这个解决方案。我们正在尝试序列化这些hibernate对象。现在,我们有很多不同的hibernate pojos正在进行逆向工程。我们不想为每个类手动编写序列化例程。如果我们遵循“只是手动将访问方法写入嵌入对象上的外键字段”的约定,我们就必须这样做。此外,即使我们这样做,pojo仍然不知道外键的字段被称为什么。相反,我们使用带有类型适配器的gson。

使用gson,我们将序列化pojo上的所有字段,并忽略包含hibernate对象的字段。当然,问题是我们没有外键字段。我们在这里需要一些信息,以便一般地序列化任何hibernate pojo。我们需要知道:

  1. 外键字段名称
  2. 外键字段值

3 个答案:

答案 0 :(得分:2)

您的方法违反了Hibernate惯例。因为Hibernate使用反射,所以约定对于Hibernate来说是必不可少的。因此,我怀疑Maouven的“遵循惯例”方法最简单。但是,如果它是不可协商的,您有两种选择。

您的第一个选择是添加瞬态getter,以公开getAddressId()函数。

public class User() {
    private String name;
    private Integer uid;
    private Address address;

    // Getters, setters...

    @Transient
    public boolean getAddressId() {
        address.getId();
    }
}

您的第二个选择是添加数据访问层以在Hibernate对象之上强加您自己的约定。这个抽象层不受Hibernate约定的约束。这样,您的POJO将由DAO(Data Access Objects)包装,您可以根据需要进行设计。

<强>更新

鉴于您的独特情况,请考虑修改序列化步骤。 GSON通常不能使用瞬态方法,但有一个扩展可以this,如here所示。

另一种解决方案是使用反射以您希望的方式复制对象,然后使用GSON序列化复制的对象。

答案 1 :(得分:0)

您的方法会导致班级数据出现冗余。在由Hibernate-生成的第一堆代码中,您可以从User Class的Address属性中获取所需的addressId:

yourUser.getAddress().getAddressId();

答案 2 :(得分:0)

两个可能(理论上讲)解决方案,但需要在Hibernate Tools进行逆向工程后手动重构:

我只是为了简洁而使用注释

1)使用映射公开列:

@Entity
class User
{
    @Id
    @Column
    private Integer uid;

    @Column
    private String name;

    @Column(name = "ADDRESS_ID", insertable = false, updatable = false)
    private Integer addressId;

    @ManyToOne
    @JoinColumn(name = "ADDRESS_ID")
    private Address address;
}

2)使用@Transient + @PostLoad:

@Entity
class User
{
    @Id
    @Column
    private Integer uid;

    @Column
    private String name;

    @Transient
    private Integer addressId;

    @ManyToOne
    @JoinColumn(name = "ADDRESS_ID")
    private Address address;

    @PostLoad
    public void postLoad()
    {
        addressId = Optional.ofNullable(address).map(Address::getId).orElse(null);
    }
}

使用JSON marshaller for JAXB可以实现另一种解决方案:

@XmlRootElement
class User
{
    @XmlID
    private Integer uid;

    private String name;

    @XmlIDREF
    private Address address;
}

您可以找到快速入门here