我一直在关注使用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。我们需要知道:
答案 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