[hibernate-dev] [feature request][discuss] smoother serializers integration?
Vlad Mihalcea
mihalcea.vlad at gmail.com
Fri May 5 03:47:52 EDT 2017
I also think we should address this Visitor pattern Lazy association
initialization in Hibernate 6. You could add a Jira issue with some
comments from this mail discussion so that we remember about it and address
it after 6.0 is released.
Vlad
On Thu, May 4, 2017 at 10:34 PM, Romain Manni-Bucau <rmannibucau at gmail.com>
wrote:
> 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
> >>>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> _______________________________________________
> 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