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

Romain Manni-Bucau rmannibucau at gmail.com
Thu May 4 15:34:35 EDT 2017


2017-05-04 19:28 GMT+02:00 Steve Ebersole <steve at hibernate.org>:

> I should clarify... if your `serialzer#serialize` call is not
> "recursively" calling into this check then my example would not work; but
> then again, neither would yours
>

Well mine works (no "would" ;)) cause jsonb implements the visitor pattern
for me in my case.

But ok, let's see this Navigable solution when out, sounds promishing.


>
> On Thu, May 4, 2017, 12:26 PM Steve Ebersole <steve at hibernate.org> wrote:
>
>> Hibernate#isInitialized is an overloaded method.  I think you want to
>> look at the different forms.
>>
>> And yes, Navigable will define visitor-based navigation. Hence the name ;)
>>
>> On Thu, May 4, 2017, 12:18 PM Romain Manni-Bucau <rmannibucau at gmail.com>
>> wrote:
>>
>>> 2017-05-04 19:16 GMT+02:00 Steve Ebersole <steve at hibernate.org>:
>>>
>>>> But your psuedo code is really just the same as:
>>>>
>>>> AnEntity e = find();
>>>> if ( isInitialized( e ) ) {
>>>>     serializer.serialize(e);
>>>> }
>>>>
>>>
>>> no cause it is done in the graph visitor and not just the root, that's
>>> the key difference.
>>>
>>>
>>>>
>>>> boolean isInitialized(Object e) {
>>>>     return Hibernate.isInitialized( e );
>>>> }
>>>>
>>>> What I was getting at with the 6.0 + Navigavble discussion is that it
>>>> would be better to base this "isInitialized" on these Navigables instead.
>>>> A Navigable is a polymorphic reference that might be an entity, a
>>>> persistent attribute, a "collection element", etc.
>>>>
>>>
>>> Would need to see it in a more concrete version but sounds tempting,
>>> would it integrate a visitor - handling cycles?
>>>
>>>
>>>>
>>>>
>>>> On Thu, May 4, 2017 at 11:46 AM Romain Manni-Bucau <
>>>> rmannibucau at gmail.com> wrote:
>>>>
>>>>> 2017-05-04 18:42 GMT+02:00 Christian Beikov <
>>>>> christian.beikov at gmail.com>:
>>>>>
>>>>>> Detecting if an object is initialized should be as easy as calling "
>>>>>> Hibernate.isInitialized(object)". If you want to know whether a
>>>>>> specic attribute of an object is initialized you'd use "Hibernate.isPropertyInitialized(object,
>>>>>> attributeName)". What you want is some kind of integration that
>>>>>> makes use of these two methods, so that if they return false, a null value
>>>>>> is used when serializing objects to XML/JSON via JAXB/JSONB. Is that
>>>>>> correct?
>>>>>>
>>>>>
>>>>> Almost, I would like one able to just disable it, this way the
>>>>> serializer doesnt need anything or knowledge of hibernate. Worse case we
>>>>> need to integrate with the serializer in a way close to the one i proposed
>>>>> for johnzon before.
>>>>>
>>>>> In pseudo code it would be:
>>>>>
>>>>> AnEntity e = find();
>>>>> Hibernate.disableLazyExceptionWithNull(e);
>>>>> serializer.serialize(e);
>>>>>
>>>>>
>>>>>> I don't know of any hook in JAXB that could be used to put that code
>>>>>> into so it works out as you'd expect it. The only other way I can think of,
>>>>>> is nulling the properties explicitly which could be done quite easily. You
>>>>>> probably gonna need just a single recursive method to do that. I don't see
>>>>>> how that method should be part of Hibernate nor how you'd expect to be able
>>>>>> to configure Hibernate so that it would do that transparently.
>>>>>>
>>>>> the switch of lazyexception to null would work wit jaxb. Otherwise you
>>>>> need some more low level integration not portable IIRC.
>>>>>
>>>>>
>>>>>> I still think the cleanest solution would be to have DTOs, which is
>>>>>> why I'd argue that such a halve solution shouldn't be part of Hibernate.
>>>>>>
>>>>>
>>>>> Think we all agree (or agreed already ;)) but created this thread
>>>>> cause i saw it often enough to be a need.
>>>>>
>>>>>
>>>>>>
>>>>>> Mit freundlichen Grüßen,
>>>>>> ------------------------------
>>>>>> *Christian Beikov*
>>>>>> Am 04.05.2017 um 18:00 schrieb Romain Manni-Bucau:
>>>>>>
>>>>>>
>>>>>>
>>>>>> 2017-05-04 17:33 GMT+02:00 Steve Ebersole <steve at hibernate.org>:
>>>>>>
>>>>>>> What exactly would this "utility one level further than existing
>>>>>>> ones" do?
>>>>>>>
>>>>>>>
>>>>>> Multiple options are possible but one is to return null instead of
>>>>>> throwing lazy exception for instance.
>>>>>>
>>>>>>
>>>>>>> And for what it is worth, IMO the new Navigable model in 6.0 will
>>>>>>> again
>>>>>>> help here.  Especially in conjunction with the Navigable visitation
>>>>>>> support.
>>>>>>>
>>>>>>
>>>>>> I'm not familiar enough but if it providers for each member a way to
>>>>>> know if it is loaded or not it can work.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> On Thu, May 4, 2017 at 10:27 AM Christian Beikov <
>>>>>>> christian.beikov at gmail.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>> > Well that is again exactly what a DTO is good for. If you as
>>>>>>> developer
>>>>>>> > want the groups to be available, you add a list of groups to that
>>>>>>> > special DTO type for that use case. In your data access layer you
>>>>>>> > somehow populate that, which is normally done by using some mapper
>>>>>>> > library like MapStruct or Dozer and then JAXB/JSONB can just work
>>>>>>> with
>>>>>>> > the DTO type without any problems.
>>>>>>> >
>>>>>>> > Now if you forget to add a JOIN FETCH to your query and you end up
>>>>>>> with
>>>>>>> > N+1 queries, that's a different problem, just like the amount of
>>>>>>> > boilerplate code needed for having DTO types for every use case.
>>>>>>> That I
>>>>>>> > try to solve with Blaze-Persistence Entity Views.
>>>>>>> >
>>>>>>> > Just a quick example to make my point here. If you have a REST
>>>>>>> endpoint
>>>>>>> > /user/{id} and want to provide the list of group names along with
>>>>>>> the
>>>>>>> > user information, you'd create a UserInfoDTO.
>>>>>>> >
>>>>>>> > @EntityView(User.class)
>>>>>>> > interface UserInfoDTO {
>>>>>>> >    String getUsername();
>>>>>>> >    @Mapping("groups.name")
>>>>>>> >    List<String> getGroups();
>>>>>>> > }
>>>>>>> >
>>>>>>> > Your repository returns an object of that type and you just pass
>>>>>>> that
>>>>>>> > object through so JAXB/JSONB can do their work. The mapping
>>>>>>> information
>>>>>>> > in the DTO is applied on a "source query" i.e. only doing the work
>>>>>>> > absolutely necessary to satisfy the requested projection.
>>>>>>> >
>>>>>>> > Implementing this by hand is by no means impossible, but rather
>>>>>>> > inconvenient I'd say, which is probably why you are seeking for
>>>>>>> other
>>>>>>> > solutions.
>>>>>>> >
>>>>>>> > In the end, you can only try to create a minimal DTO that has
>>>>>>> exactly
>>>>>>> > the fields you want to be serialized or annotate your existing
>>>>>>> entities
>>>>>>> > with those "ignore" annotations and hope for the best. I don't see
>>>>>>> how
>>>>>>> > hibernate could or should help in any of the two cases.
>>>>>>> >
>>>>>>> > Mit freundlichen Grüßen,
>>>>>>> > ------------------------------------------------------------
>>>>>>> ------------
>>>>>>> > *Christian Beikov*
>>>>>>> > Am 04.05.2017 um 16:59 schrieb Romain Manni-Bucau:
>>>>>>> > > Sure. If you add any conversion logic then you are clearly out of
>>>>>>> > > hibernate scope and the problem doesnt appear anymore. Here is a
>>>>>>> > > trivial example (hopefully trivial at least ;))
>>>>>>> > >
>>>>>>> > > User 1 - n Group
>>>>>>> > >
>>>>>>> > > In json we would get something like {username:...,groups:[group1,
>>>>>>> > > group2]}, no issue to know if group should be loaded or not
>>>>>>> since this
>>>>>>> > > part of the logic is in the mapper layer.
>>>>>>> > >
>>>>>>> > > So yes you can say "not my problem" but next framework will
>>>>>>> > > immediately ask "how do i know" and you likely end like all
>>>>>>> > > spring-data-rest recommandation with a specific mapping and not a
>>>>>>> > > framework solution which is the target of that thread - at least
>>>>>>> what
>>>>>>> > > I tried to explain ;).
>>>>>>> > >
>>>>>>> > > 2017-05-04 16:41 GMT+02:00 Christian Beikov
>>>>>>> > > <christian.beikov at gmail.com <mailto:christian.beikov at gmail.com
>>>>>>> >>:
>>>>>>> > >
>>>>>>> > >     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
>>>>>>> >
>>>>>>> > >>
>>>>>>> > >
>>>>>>> > >
>>>>>>> >
>>>>>>> > _______________________________________________
>>>>>>> > hibernate-dev mailing list
>>>>>>> > hibernate-dev at lists.jboss.org
>>>>>>> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>>>>>> _______________________________________________
>>>>>>> hibernate-dev mailing list
>>>>>>> hibernate-dev at lists.jboss.org
>>>>>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>>>>>>
>>>>>>
>>>>>>
>>>>>>


More information about the hibernate-dev mailing list