Reputation: 2986
We're using entity classes for two purposes:
@Entity
Imagine an @Entity
has a number of bulky collections, e.g.:
@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 ... */
}
Now, we work with Customer
in two major ways:
My preferred solution would be explicit initialization of collections for the case 1, and keeping them null
or empty for the case 2.
The problem is that when Jackson serializes an object into JSON, it goes over all properties, including collection ones, so they are forced to be initialized. Adding @JsonIgnore
is not an option (we need those collections for case 1), adding @Transient
to keep Hibernate away from them is not an option either (we have to be able to store collections after editing).
Another alternative would be, of course, creating a different model of Customer
without collections and using that for scenario 2, but that means maintaining two varieties of the same entity and I'd like to avoid that.
How can I disable Hibernate's implicitly loading of these collections, so that they are only initialized explicitly (via e.g. Hibernate.initialize(customer.orders)
), while retaining the possibility of persisting them when needed?
Upvotes: 1
Views: 1395
Reputation: 2986
Eventually I've solved it in the "DTO-fashion" but with minimal overhead, by adding an alternative getter for each property, like so:
@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;
}
...
}
Upvotes: 1
Reputation: 23562
There is no way to do it in Hibernate.
Alternatives:
Upvotes: 1
Reputation: 5523
The following is just one possible solution and depends on your environment.
There's a project called "jackson-datatype-hibernate" from the FasterXML project. You can find it at https://github.com/FasterXML/jackson-datatype-hibernate which allows to define a custom serializer with includes disabling of lazy fields. (I think this default for this serializer).
Code could look like the following:
ObjectMapper mapper = new ObjectMapper();
Hibernate4Module hibernateModule = new Hibernate4Module();
mapper.registerModule(hibernateModule);
Upvotes: 0