For now I integrated it with johnzon: @Provider public class ApiHibernateJsonbProvider<T> extends JsonbJaxrsProvider<T> { @Override protected Jsonb createJsonb() { return JsonbProvider.provider().create() .withConfig(new JsonbConfig() .setProperty("johnzon.serialize-value-filter", (SerializeValueFilter) this::shouldIgnoreField)) .build(); }
private boolean shouldIgnoreField(final String ignoredPropertyName, final Object value) { return (HibernateProxy.class.isInstance(value) && HibernateProxy.class.cast(value).getHibernateLazyInitializer().isUninitialized()) || PersistentCollection.class.isInstance(value) && !PersistentCollection.class.cast(value).wasInitialized(); } } So maybe an utility allowing to just integrate with any serializer (which already browse the model) would be smoother than a specific integration. I also think spring (and its trendy boot flavor) does that kind of thing through spring-data-rest. Romain Manni-Bucau @rmannibucau <https://twitter.com/rmannibucau> | Blog <https://blog-rmannibucau.rhcloud.com> | Old Blog <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> | LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory <https://javaeefactory-rmannibucau.rhcloud.com> 2017-05-04 10:04 GMT+02:00 Emmanuel Bernard <emman...@hibernate.org>: > I was very much in the Vlad, Steve, Christian camp until relatively > recently. One of my main concern being that replacing a proxy by null > was really sending the wrong message. So I was against having Hibernate > ORM facilitate such a transformation. > > I am changing my mind because I am realizing that a lot of applications > are less complex that my perceived median. A lot of apps really just > want data to be fetched out and then passed to jackson (implicitly) and > pushed out as a REST response in JSON or some other serialization > protocol. > > So while we could try and keep the stance that such a solution should > remain out of scope of Hibernate ORM core, we should have a very smooth > integration with something like MapStruct to create such bounded DTO on > the fly. Ideally with as close to zero code as possible from the user > point of view. > I can't really describe how that could look like because I am not > familiar enough with MapStruct but I think it should have the following > characteristics: > > 1. do an implicit binding between the mapped object graph and a detached > object graph with a 1-1 mapping of type and replacing lazy objects and > collections with null. That's the smoothest approach and the most > common use case but also the one where an inexperienced person could > shoot at someone else's foot > 2. do a binding between the mapped object graph and a detached version of > that object graph with a 1-1 mapping of type, but declaratively > expressing the boundaries for the detached version. This enforces a > clear thinking of the boundaries and will load lazy data in case the > object graph loaded is missing a bit. I like the idea on principle but > I think it overlaps a lot with the fetch graph. > 3. offer a full integration between MapStruct and Hibernate ORM by > letting people express a full fledge MapStruct transformation between > the managed object graph and a different target structure > > I favored MapStruct over Dozer because we know the MapStruct lead quite > well ;) > > Note however that the MapStruct approach requires an explicit object > copy, it feels a bit sad to have to double memory consumption. But that > might be a good enough approach and bypassing the managed object > creation leads to questions around the Persistence Context contract > where loading an object supposedly means it will be in the PC. > Maybe a constructor like query syntax allowing to reference a MapStruct > conversion logic might work? > > select mapStruct('order-and-items', o) from Order o left join fetch > o.items > > Emmanuel > > > On Wed 17-04-19 14:29, Vlad Mihalcea wrote: > >Hi, > > > >Although I keep on seeing this request from time to time, I still think > >it's more like a Code Smell. > >Entities are useful for when you plan to modify them. Otherwise, a DTO > >projection is much more efficient, and you don't suffer from > >LazyInitializationException. > > > >With the ResultTransformer, you can even build graphs of entities, as > >explained in this article; > > > >https://vladmihalcea.com/2017/04/03/why-you-should-use-the-hibernate- > resulttransformer-to-customize-result-set-mappings/ > > > >Due to how Hibernate Proxies are handled, without Bytecode Enhancement, > >it's difficult to replace a Proxy with null after the Session is closed. > If > >we implemented this, we'd have to take into consideration both Javassist > >and ByteBuddy as well as ByteCode Enhancements. > > > >all in all, the implementation effort might not justify the benefit, and > >I'm skeptical of offering a feature that does not encourage data access > >Best Practices. > > > >Vlad > > > >On Wed, Apr 19, 2017 at 2:18 PM, Christian Beikov < > >christian.bei...@gmail.com> wrote: > > > >> Hey Romain, > >> > >> I don't think it is a good idea to expose entities directly if you > >> really need a subset of the data. > >> Reasons for that thinking are that it gets hard to define what needs to > >> be fetched or is safe to be used for a particular use case. Obviously > >> serialization is like a follow-up problem. > >> I see 2 possible solutions to the problem and both boil down to the use > >> of DTOs. > >> > >> 1. Use an object mapper(e.g. Dozer) that maps entity object graphs to > >> custom DTO types. > >> 2. Use specialized DTOs in queries. > >> > >> > >> Implementing 1. does not help you with lazy loading issues and 2. might > >> require very intrusive changes in queries which is why I implemented > >> Blaze-Persistence Entity Views > >> <https://github.com/beikov/blaze-persistence#entity-view-usage>. > >> This is a library that allows you to define DTOs with mappings to the > >> entity. In a query you can define that you want results to be > >> "materialized" as instances of the DTO type. > >> This reduces the pain induced by properly separating the "presentation > >> model" from the "persistence model" and at the same time will improve > >> the performance by utilizing the mapping information. > >> I don't want to advertise too much, just wanted to say that I had the > >> same issues over and over which is why I started that project. > >> > >> Mit freundlichen Grüßen, > >> ------------------------------------------------------------ > ------------ > >> *Christian Beikov* > >> Am 19.04.2017 um 10:51 schrieb Romain Manni-Bucau: > >> > Hi guys, > >> > > >> > Short sumarry: Wonder if hibernate could get a feature to kind of > either > >> > unproxy or freeze the entities once leaving the managed context to > avoid > >> > uncontrolled lazy loading on one side and serialization issues on > another > >> > side. > >> > > >> > Use case example: a common example is a REST service exposing directly > >> > hibernate entities (which is more and more common with microservice > >> > "movement"). > >> > > >> > Objective: the goal is to not need any step - or reduce them a lot - > >> > between the hibernate interaction and a potential serialization to > avoid > >> > issues with lazy loading and unexpected loading. Today it requires > some > >> > custom and hibernate specific logic in the serializer which kind of > >> breaks > >> > the transversality of the two concerns (serialization and object > >> > management/loading). > >> > > >> > > >> > Implementation options I see: > >> > > >> > 1. a callback requesting if the lazy relationship should be fetched, > >> > something like > >> > > >> > public interface GraphVisitor { > >> > boolean shouldLoad(Object rootEntity, Property property); > >> > } > >> > > >> > 2. An utility to remove any proxy potentially throwing an exception > and > >> > replacing the value by null or an empty collection, something like > >> > > >> > MyEntity e = Hibernate.deepUnproxy(entity); > >> > > >> > 3. A switch of the proxy implementation, this is close to 2 but > wouldn't > >> > require a call to any utility, just a configuration in the persistence > >> unit. > >> > > >> > Side note: of course all 3 options can be mixed to create a single > >> solution > >> > like having 3 implemented based on 1 for instance. > >> > > >> > Configuration proposal: this would be activated through a property in > the > >> > persistence unit (this shouldn't be only global IMHO cause otherwise > you > >> > can't mix 2 kind of units, like one for JSF and one for JAX-RS to be > >> > concrete). This should also be activable as a query hint i think - but > >> more > >> > a nice to have. > >> > > >> > > >> > What this feature wouldn't be responsible for: cycles. If > relationships > >> are > >> > bidirectional then the unproxied entity would still "loop" if you > browse > >> > the object graph - this responsability would stay in the consumer > since > >> it > >> > doesn't depend on hibernate directly but more on a plain object > handling. > >> > > >> > What do you think? > >> > > >> > > >> > Romain Manni-Bucau > >> > @rmannibucau <https://twitter.com/rmannibucau> | Blog > >> > <https://blog-rmannibucau.rhcloud.com> | Old Blog > >> > <http://rmannibucau.wordpress.com> | Github <https://github.com/ > >> rmannibucau> | > >> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory > >> > <https://javaeefactory-rmannibucau.rhcloud.com> > >> > _______________________________________________ > >> > hibernate-dev mailing list > >> > hibernate-dev@lists.jboss.org > >> > https://lists.jboss.org/mailman/listinfo/hibernate-dev > >> > >> _______________________________________________ > >> hibernate-dev mailing list > >> hibernate-dev@lists.jboss.org > >> https://lists.jboss.org/mailman/listinfo/hibernate-dev > >> > >_______________________________________________ > >hibernate-dev mailing list > >hibernate-dev@lists.jboss.org > >https://lists.jboss.org/mailman/listinfo/hibernate-dev > _______________________________________________ > hibernate-dev mailing list > hibernate-dev@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/hibernate-dev > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev