我们将实体类用于两个目的:
@Entity
想象一下@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 ... */
}
现在,我们以两种主要方式与Customer
合作:
我首选的解决方案是显式初始化集合 1 ,并保留null
或为空 2
问题在于,当Jackson将一个对象序列化为JSON时,它会覆盖所有属性,包括集合属性,因此它们被强制初始化。添加@JsonIgnore
不是一个选项(我们需要这些集合用于 1 ),添加@Transient
以使Hibernate远离它们也不是一个选项(我们必须能够在编辑后存储馆藏。)
另一种选择当然是创建一个不带集合的Customer
的不同模型,并将其用于场景 2 ,但这意味着维护同一实体的两个变种而且我'我想避免这种情况。
如何禁用Hibernate隐式加载这些集合,以便只显式初始化(例如Hibernate.initialize(customer.orders)
),同时保留在需要时保留它们的可能性?
答案 0 :(得分:1)
在Hibernate中无法做到这一点。
备选方案:
答案 1 :(得分:1)
最终我在&#34; DTO-fashion&#34;中解决了它。但是开销最小,为每个属性添加一个替代的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;
}
...
}
答案 2 :(得分:0)
以下只是一种可能的解决方案,取决于您的环境。
FasterXML项目中有一个名为“jackson-datatype-hibernate”的项目。您可以在https://github.com/FasterXML/jackson-datatype-hibernate找到它,它允许定义自定义序列化程序,包括禁用惰性字段。 (我认为这个序列化程序的默认值。)
代码可能如下所示:
ObjectMapper mapper = new ObjectMapper();
Hibernate4Module hibernateModule = new Hibernate4Module();
mapper.registerModule(hibernateModule);