Java Hibernate:避免对集合进行隐式初始化
我们使用实体类有两个目的:Java Hibernate:避免对集合进行隐式初始化,java,hibernate,jpa,collections,jackson,Java,Hibernate,Jpa,Collections,Jackson,我们使用实体类有两个目的: 作为数据库模型,即Hibernate@Entity 作为数据模型作为JSON发送到前端 假设一个@实体有许多庞大的集合,例如: @Entity @Table(name = "customer") public class Customer { @Id private Integer id; @Column(name = "name") private String name; @OneToMany(mappedBy = "
@Entity
@实体
有许多庞大的集合,例如:
@Entity
@Table(name = "customer")
public class Customer {
@Id
private Integer id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "customer", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Order> orders;
@OneToMany(mappedBy = "customer", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Counterparty> counterparties;
/* ... a lot of other properties, including collections ... */
}
@实体
@表(name=“客户”)
公共类客户{
@身份证
私有整数id;
@列(name=“name”)
私有字符串名称;
@OneToMany(mappedBy=“customer”,fetch=FetchType.LAZY,cascade=CascadeType.ALL)
私人名单订单;
@OneToMany(mappedBy=“customer”,fetch=FetchType.LAZY,cascade=CascadeType.ALL)
私人上市交易对手;
/*…许多其他属性,包括集合*/
}
现在,我们以两种主要方式与客户合作:
null
或案例2的集合为空
问题是,当Jackson将一个对象序列化为JSON时,它会覆盖所有属性,包括集合属性,因此它们必须被初始化。添加@JsonIgnore
不是一个选项(对于案例1,我们需要这些集合),添加@Transient
使其远离休眠也不是一个选项(编辑后我们必须能够存储集合)
当然,另一种选择是,创建一个不同的客户
模型,不使用集合,并将其用于场景2,但这意味着维护同一实体的两个品种,我希望避免这种情况
如何禁用Hibernate对这些集合的隐式加载,使它们只进行显式初始化(例如通过
Hibernate.initialize(customer.orders)
),同时保留在需要时持久化它们的可能性?以下只是一种可能的解决方案,取决于您的环境
FasterXML项目中有一个名为“jackson数据类型hibernate”的项目。您可以在其中找到它,它允许定义自定义序列化程序,包括禁用惰性字段。(我认为这是这个序列化程序的默认设置)
代码可能如下所示:
ObjectMapper mapper = new ObjectMapper();
Hibernate4Module hibernateModule = new Hibernate4Module();
mapper.registerModule(hibernateModule);
在Hibernate中没有办法做到这一点 备选方案:
最终,我以“DTO方式”解决了这个问题,但开销最小,为每个属性添加了一个替代getter,如下所示:
@Entity
@Table(name = "customer")
public class Customer {
...
@OneToMany(mappedBy = "customer", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonIgnore
private List<Order> orders;
/* "Normal" getter to be used in the back-end */
@JsonIgnore // <-- Important as it hides it from Jackson
public List<Order> getOrders() {
return orders;
}
/* Non-initializing getter for serialization for the front-end */
public List<Order> getOrdersNonInit() {
return Hibernate.isInitialized(orders) ? orders : null;
}
...
}
@实体
@表(name=“客户”)
公共类客户{
...
@OneToMany(mappedBy=“customer”,fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@杰索尼奥雷
私人名单订单;
/*后端要使用的“普通”getter*/
@JsonIgnore//可能是解决这个问题的一个好方法,但是它真的很难理解如何使用它,因为它没有任何文档或示例,而且Java文档非常稀少。最后我放弃了它,创建了替代的非初始化getter。除了链接的依赖项之外,这些代码就是您所需要的一切。只需序列化即可具有此映射器的对象。此映射器的默认行为应该是不序列化惰性集合。