[hibernate-dev] [feature request][discuss] smoother serializers integration?

Christian Beikov christian.beikov at gmail.com
Thu May 4 10:41:01 EDT 2017


I don't understand what you mean by "you put that logic in the 
conversion", could you elaborate?


Mit freundlichen Grüßen,
------------------------------------------------------------------------
*Christian Beikov*
Am 04.05.2017 um 16:32 schrieb Romain Manni-Bucau:
> Few more points:
>
> 1. Dto dont help at any moment - or you put that logic in the 
> conversion and you are back to start
> 2. Making jaxb/jsonb easy to integrate is the goal IMO. No need to 
> integrate with them but just provide some utility one level further 
> than existing ones
>
> Le 4 mai 2017 16:13, "Steve Ebersole" <steve at hibernate.org 
> <mailto:steve at hibernate.org>> a écrit :
>
>     Oops, that (3) in previous reply should have read:
>     3. supporting each format creates a new "optional" library dependency
>
>     Overall, I like Christian's approach as a potential generalized
>     approach to
>     this.  Basically a combination of
>
>        1. a query used to provide the "view source values"
>        2. some indication of how to map those "source values" to your
>     view model
>
>
>     And again, I think 6.0's improved dynamic-instantiation queries are a
>     simple, already-built-in way to achieve that for most cases.  But
>     I am open
>     to discussing a way to supply that combination via API if we deem that
>     would be good - although then I'd also question how the current
>     TupleTransformer does not meet that need.
>
>     On Thu, May 4, 2017 at 8:43 AM Steve Ebersole <steve at hibernate.org
>     <mailto:steve at hibernate.org>> wrote:
>
>     > Were there a standard "represent something in XML-ish format"
>     contract
>     > portable across a number of formats (XML, JAXB, JSON, etc) then
>     I'd be more
>     > inclined to agree with this.  But as it is, supporting this
>     would mean
>     > Hibernate implementing multiple such contracts, one per format. 
>     However,
>     >
>     >    1. these formats are not our core competency
>     >    2. maintaining a complete set of these transformers across
>     all the
>     >    popular formats du-jour is a large undertaking
>     >    3. I am not convinced that
>     >
>     > All of these increase the technical risk.
>     >
>     > Additionally, to properly support this we'd really need the
>     ability to
>     > then "map" multiple views for a given entity-graph-root.  What I
>     mean by
>     > that, is that such DTO approaches often need multiple "views" of
>     a given
>     > entity, e.g. a CompanyListDTO, CompanyOverviewDTO,
>     > CompanyDetailsGeneralDTO, etc for a Company entity. The point of
>     this is
>     > that
>     >
>     >    1. the transformers for these are specific to each DTO type
>     and would
>     >    be applied per-transformation
>     >    2. were Hibernate to "provide" this for applications
>     >
>     > IMO the use of queries to obtain views is logical. Populating
>     each of
>     > those specific DTOs (CompanyListDTO, etc) in the most efficient
>     way is
>     > going to require very different SQL for each DTO.  This implies
>     some kind
>     > of "mapping" to be able associate each DTO with query.
>     >
>     > Given 6.0's improved dynamic-instantiation support, I even think
>     that is a
>     > great solution as well *for most cases*.
>     >
>     > So, while my objection has a "practical impact" component, I
>     also just
>     > question whether Hibernate integrating with each format's
>     "serializer" is
>     > the proper solution.
>     >
>     >
>     >
>     > On Thu, May 4, 2017 at 5:08 AM Christian Beikov <
>     > christian.beikov at gmail.com <mailto:christian.beikov at gmail.com>>
>     wrote:
>     >
>     >> This is exactly what I am trying to do with Blaze-Persistence
>     Entity
>     >> Views, making DTOs sexy and efficient :)
>     >>
>     >> Here a quick overview of how that looks like right now:
>     >>
>     >>
>     https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#first-entity-view-query
>     <https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#first-entity-view-query>
>     >>
>     >> One of my targets is to make it possible to do something like this
>     >>
>     >> entityManager.createQuery("FROM Order o",
>     OrderDTO.class).getResultList()
>     >>
>     >> and get an optimal query, as well as objects with only the
>     necessary
>     >> contents.
>     >>
>     >> Maybe we can collaborate on that somehow?
>     >>
>     >>
>     >> Mit freundlichen Grüßen,
>     >>
>     ------------------------------------------------------------------------
>     >> *Christian Beikov*
>     >> Am 04.05.2017 um 10:20 schrieb Emmanuel Bernard:
>     >> > Following up a bit on my previous email.
>     >> >
>     >> > While a core integration might be best I think, if there are
>     too much
>     >> > reluctance, we can start with a dedicated hibernate-dto or
>     whatever
>     >> > module or even separate project that makes life easier for
>     these "pass
>     >> > through" use cases. This could be in the form of a wrapper
>     API of sort
>     >> > and hence not affect existing Hibernate ORM APIs.
>     >> >
>     >> > Note that the ResultTransformer approach feels like it goes a
>     long way
>     >> > towards fixing the problem but as demonstrated in Vlad's article
>     >> >
>     >>
>     https://vladmihalcea.com/2017/04/03/why-you-should-use-the-hibernate-resulttransformer-to-customize-result-set-mappings/
>     <https://vladmihalcea.com/2017/04/03/why-you-should-use-the-hibernate-resulttransformer-to-customize-result-set-mappings/>
>     >> > it still requires quite a bit of code and a special DTO
>     constructor
>     >> > object. That's what we need to get rid of I think.
>     >> >
>     >> > Emmanuel
>     >> >
>     >> > On Thu 17-05-04 10:04, Emmanuel Bernard wrote:
>     >> >> 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/
>     <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.beikov at gmail.com
>     <mailto:christian.beikov at 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
>     <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
>     <https://twitter.com/rmannibucau>> |  Blog
>     >> >>>>> <https://blog-rmannibucau.rhcloud.com
>     <https://blog-rmannibucau.rhcloud.com>> | Old Blog
>     >> >>>>> <http://rmannibucau.wordpress.com
>     <http://rmannibucau.wordpress.com>> | Github <https://github.com/
>     >> >>>> rmannibucau> |
>     >> >>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau
>     <https://www.linkedin.com/in/rmannibucau>> | JavaEE Factory
>     >> >>>>> <https://javaeefactory-rmannibucau.rhcloud.com
>     <https://javaeefactory-rmannibucau.rhcloud.com>>
>     >> >>>>> _______________________________________________
>     >> >>>>> hibernate-dev mailing list
>     >> >>>>> hibernate-dev at lists.jboss.org
>     <mailto:hibernate-dev at lists.jboss.org>
>     >> >>>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>     <https://lists.jboss.org/mailman/listinfo/hibernate-dev>
>     >> >>>> _______________________________________________
>     >> >>>> hibernate-dev mailing list
>     >> >>>> hibernate-dev at lists.jboss.org
>     <mailto:hibernate-dev at lists.jboss.org>
>     >> >>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>     <https://lists.jboss.org/mailman/listinfo/hibernate-dev>
>     >> >>>>
>     >> >>> _______________________________________________
>     >> >>> hibernate-dev mailing list
>     >> >>> hibernate-dev at lists.jboss.org
>     <mailto:hibernate-dev at lists.jboss.org>
>     >> >>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>     <https://lists.jboss.org/mailman/listinfo/hibernate-dev>
>     >> >> _______________________________________________
>     >> >> hibernate-dev mailing list
>     >> >> hibernate-dev at lists.jboss.org
>     <mailto:hibernate-dev at lists.jboss.org>
>     >> >> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>     <https://lists.jboss.org/mailman/listinfo/hibernate-dev>
>     >> > _______________________________________________
>     >> > hibernate-dev mailing list
>     >> > hibernate-dev at lists.jboss.org
>     <mailto:hibernate-dev at lists.jboss.org>
>     >> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>     <https://lists.jboss.org/mailman/listinfo/hibernate-dev>
>     >>
>     >> _______________________________________________
>     >> hibernate-dev mailing list
>     >> hibernate-dev at lists.jboss.org
>     <mailto:hibernate-dev at lists.jboss.org>
>     >> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>     <https://lists.jboss.org/mailman/listinfo/hibernate-dev>
>     >>
>     >
>     _______________________________________________
>     hibernate-dev mailing list
>     hibernate-dev at lists.jboss.org <mailto:hibernate-dev at lists.jboss.org>
>     https://lists.jboss.org/mailman/listinfo/hibernate-dev
>     <https://lists.jboss.org/mailman/listinfo/hibernate-dev>
>



More information about the hibernate-dev mailing list