Various expectation changes in hibernate-core after consolidating hibernate-entitymanager
by Steve Ebersole
There are a number of "expectation changes" that come about from
consolidating hibernate-entitymanger into hibernate-core. Some we have
discussed; some we have not. Hopefully we can come to a consensus regards
how to deal with these changes...
The first one is different exception types. We have discussed this
before. For now, in an effort to fix test failures and move forward with
developing, I simply changed failing tests to expect the JPA defined
exceptions. I had mentioned, where possible, to to throw a combination of
the 2 expected exceptions. Generally this falls into 2 discrete categories:
1. JPA expects a PersistenceException and we have historically thrown a
HibernateException
2. JPA expects some form of JDK RuntimeException
(IllegalArgumentException, IllegalStateException, etc) and we have
historically thrown a HibernateException
It is unfortunate that Java does not allow exceptions to be defined by
means of interfaces; that's the only "clean" way I see to do this - that
would have allowed us to define concrete exception classes that extend
PersistenceException, IllegalArgumentException, etc and that implement
HibernateException.
So I see 3 potential solutions (feel free to bring up others).
1. Just move to JPA expected exceptions.
2. Have HibernateException extend PersistenceException and just not
worry about the change in expectation in regards to that second category.
3. Push exception handling behind a strategy. This would have to be a
pretty specific strategy for very specific cases.
The first and second options are pretty self-explanatory and
straight-forward so I won't go into detail there. Just realize that these
change the expectation for the user. They'd have to change their code to
catch these JPA-defined exceptions.
The other option, I see, is to h
The third option is perfect in theory, but it is very tedious. For
example, take the case of trying to perform some operation on a closed
Session/EntityManager. Hibernate historically threw a HibernateException
here. JPA says that should result in an IllegalStateException. So in
SessionImpl#checkOpen, when the Session/EntityManager is closed, we'd call
out to the strategy to handle that condition. Even more, Hibernate
(historically) and JPA disagree about which methods getting called on a
closed Session/EntityManager should lead to an exception. For example, JPA
says calling EntityManager#close on a closed EntityManager should result in
an exception; Hibernate historically did not care if you called
Session#close on a closed Session. So that is a special case, and every
one of those special cases would have to be exposed and handled in the
exception handling strategy in additional to the general cases.
Another change in expectation is in regards to operations outside of a
transaction, which I consider a questionable pattern anyway. Hibernate
historically allowed that; JPA explicitly disallows it. In a way this
could fall under the exception discussion above, meaning we could push that
distinction behind the exception handling strategy. Or we could decide
that we are going to stop supporting that.
There are a lot of other highly questionable things I have seen in the
tests that JPA explicitly disallows that I think we ought to just stop
supporting and opt for the JPA way, although I am open to discussing them
if any feels strongly about them. Some of these include:
- Asking a Session if is contains (Session/EntityManager#contains) a
non-entity. Hibernate historically would just return false. JPA states
that should be an exception.
- Accessing Session/EntityManager#getTransaction. JPA says that is only
allowed for JDBC transactions. Hibernate always allows it.
If we go the route of an "exception handling strategy" a lot of the other
points I mentioned above could just be pushed behind that strategy. But I
really want to start looking critically at what we support today that we
maybe really should not be.
8 years, 7 months
Re: [hibernate-dev] 5.2 Java 8 Optional support
by Steve Ebersole
Good point about the design/intention of Optional. I hadn't seen that
before.
I included it here because I have seen requests for it.
Serializability is not an argument for me. Yes *if* you plan on detaching
the model and passing it remotely Serializable is a requirement and
Optional could not be used. But you don't have to detach your model and
pass it remotely, of course. The design/intention angle is much more
compelling to me.
So I agree we should probably remove that part. Which is more than ok with
me :)
On Wed, May 4, 2016, 3:52 PM Andrej Golovnin <andrej.golovnin(a)gmail.com>
wrote:
> Hi Steve,
>
> > 1. Support models which define attributes using Optional
>
> -1. Why:
>
> 1. JPA 2.1 Spec. §2.1 The Entity Class:
> If an entity instance is to be passed by value as a detached
> object (e.g., through a remote interface), the entity class must
> implement the Serializable interface.
>
> Optional is not Serializable. Therefore when you use detached
> entities in your application, then you cannot use Optional as
> field type.
>
> 2. Using Optional as field type is considered a misuse of the API.
> See the comment from Stuart Marks:
>
> http://stackoverflow.com/questions/23454952/uses-for-java8-optional?answe...
>
> IntelliJ IDEA warns you for example when you use Optional
> as field type.
>
> Best regards,
> Andrej Golovnin
>
> > 2. Allow retrieving Objects from Hibernate as Optional
> >
> > The second part is really about allowing users to request that Hibernate
> > return Optional in cases where the result may be null. This will be very
> > targeted to cases where the user ask Hibernate to get an entity, e.g.
> > Session#get, Session#find, *LoadAccess#load, Query#getSingleResult,
> > Query#uniqueResult, etc. I am against adding any more overloaded
> > Session#get methods, so I will actually limit that to *LoadAccess#load.
> So
> > here I propose adding:
> >
> > 1. Optional<R> *LoadAccess<R>#loadOptional()
> > 2. Optional<R> Query<R>#uniqueResultOptional()
> >
> >
> > The second part is about accepting Optionals from the user. The biggest
> > use case here is the use of Optional in the application domain model for
> > persistent attributes. Again tis breaks down into 2 concerns:
> >
> > 1. Getting/setting values of such persistent attributes.
> > 2. Appropriately marking column(s) of such persistent attributes
> > nullable (by default, at least)
> >
> > The first concern initially seems like a god candidate for Types, but it
> > really does not fit. I think the better place to deal with this is
> > PropertyAcess and specifically the Getter and Setter it returns. The
> > logical there being that the "type" is still the <T>, not the Optional.
> >
> > Handling column nullability will be a challenge given the current state
> of
> > annotation binding code.
> > Another consideration is accepting Query parameters that are Optional.
> It
> > is a silly idea to pass an Optional as a parameter, I agree. But there
> are
> > places it legitimately comes up:
> >
> > - setParameter( ..., a.getSomeOptional() ) - where getSomeOptional is
> an
> > Optional
> > - setProperties( a ) - where a is a bean that defines Optional(s)
> >
> > Anyway, that's the plan and I'm sticking to it (unless I hear feedback).
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev(a)lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>
>
8 years, 7 months
Re: [hibernate-dev] HHH-9440 Support for Java 8: parameter names
by Steve Ebersole
On Mon, Mar 28, 2016 at 1:22 PM Lovro Pandzic <lovro.pandzic(a)gmail.com>
wrote:
> I am confused how you are "mind mapping" PreparedStatement parameters and
>> entity construction into the same conversation. We are not instantiating
>> entities based on PreparedStatement parameters....
>>
>
> I'm not sure I understand you, I haven't mentioned PreparedStatement
> parameters anywhere.
>
Well you mentioned Java 8 parameters names in the subject. I have no idea
what "Java 8 parameter names" might mean outside of the support added in
Java 8 for named parameter binding. So if that's not what you mean, what
do you mean?
Based on some of your other replies, perhaps you are confusing "parameter
names" (PreparedStatement) and "column names" (ResultSet)?
What you propose is to delay the entity instantiation and create the entity
>> instance from after we have the hydrated state.
>
>
> Yes, the requirement for this to work is that before calling constructor
> you have all arguments and target parameter names available.
>
Right, which precludes lazy loading; which is my point on the Jira.
8 years, 7 months
Re: [hibernate-dev] 5.2 Java 8 Optional support
by Andrej Golovnin
Hi Steve,
> 1. Support models which define attributes using Optional
-1. Why:
1. JPA 2.1 Spec. §2.1 The Entity Class:
If an entity instance is to be passed by value as a detached
object (e.g., through a remote interface), the entity class must
implement the Serializable interface.
Optional is not Serializable. Therefore when you use detached
entities in your application, then you cannot use Optional as
field type.
2. Using Optional as field type is considered a misuse of the API.
See the comment from Stuart Marks:
http://stackoverflow.com/questions/23454952/uses-for-java8-optional?answe...
IntelliJ IDEA warns you for example when you use Optional
as field type.
Best regards,
Andrej Golovnin
> 2. Allow retrieving Objects from Hibernate as Optional
>
> The second part is really about allowing users to request that Hibernate
> return Optional in cases where the result may be null. This will be very
> targeted to cases where the user ask Hibernate to get an entity, e.g.
> Session#get, Session#find, *LoadAccess#load, Query#getSingleResult,
> Query#uniqueResult, etc. I am against adding any more overloaded
> Session#get methods, so I will actually limit that to *LoadAccess#load. So
> here I propose adding:
>
> 1. Optional<R> *LoadAccess<R>#loadOptional()
> 2. Optional<R> Query<R>#uniqueResultOptional()
>
>
> The second part is about accepting Optionals from the user. The biggest
> use case here is the use of Optional in the application domain model for
> persistent attributes. Again tis breaks down into 2 concerns:
>
> 1. Getting/setting values of such persistent attributes.
> 2. Appropriately marking column(s) of such persistent attributes
> nullable (by default, at least)
>
> The first concern initially seems like a god candidate for Types, but it
> really does not fit. I think the better place to deal with this is
> PropertyAcess and specifically the Getter and Setter it returns. The
> logical there being that the "type" is still the <T>, not the Optional.
>
> Handling column nullability will be a challenge given the current state of
> annotation binding code.
> Another consideration is accepting Query parameters that are Optional. It
> is a silly idea to pass an Optional as a parameter, I agree. But there are
> places it legitimately comes up:
>
> - setParameter( ..., a.getSomeOptional() ) - where getSomeOptional is an
> Optional
> - setProperties( a ) - where a is a bean that defines Optional(s)
>
> Anyway, that's the plan and I'm sticking to it (unless I hear feedback).
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev(a)lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
8 years, 7 months
5.2 Java 8 Optional support
by Steve Ebersole
Since 5.2 is moving to baseline on Java 8 we've been looking at Java 8
features we might leverage in Hibernate and allow users to leverage.
The first one I am tackling is "support for Optional", which will have the
following parts:
1. Support models which define attributes using Optional
2. Allow retrieving Objects from Hibernate as Optional
The second part is really about allowing users to request that Hibernate
return Optional in cases where the result may be null. This will be very
targeted to cases where the user ask Hibernate to get an entity, e.g.
Session#get, Session#find, *LoadAccess#load, Query#getSingleResult,
Query#uniqueResult, etc. I am against adding any more overloaded
Session#get methods, so I will actually limit that to *LoadAccess#load. So
here I propose adding:
1. Optional<R> *LoadAccess<R>#loadOptional()
2. Optional<R> Query<R>#uniqueResultOptional()
The second part is about accepting Optionals from the user. The biggest
use case here is the use of Optional in the application domain model for
persistent attributes. Again tis breaks down into 2 concerns:
1. Getting/setting values of such persistent attributes.
2. Appropriately marking column(s) of such persistent attributes
nullable (by default, at least)
The first concern initially seems like a god candidate for Types, but it
really does not fit. I think the better place to deal with this is
PropertyAcess and specifically the Getter and Setter it returns. The
logical there being that the "type" is still the <T>, not the Optional.
Handling column nullability will be a challenge given the current state of
annotation binding code.
Another consideration is accepting Query parameters that are Optional. It
is a silly idea to pass an Optional as a parameter, I agree. But there are
places it legitimately comes up:
- setParameter( ..., a.getSomeOptional() ) - where getSomeOptional is an
Optional
- setProperties( a ) - where a is a bean that defines Optional(s)
Anyway, that's the plan and I'm sticking to it (unless I hear feedback).
8 years, 7 months
What's the identity of Hibernate OGM's "public API" module?
by Sanne Grinovero
I'm reviewing how we expect people to use the Hibernate OGM modules on WildFly.
Scott mentioned that the JPA subsystem of WildFly automatically adds
the "org.hibernate.ogm" module when the
org.hibernate.ogm.jpa.HibernateOgmPersistence persistence provider is
set.
See also :
- https://docs.jboss.org/author/display/WFLY10/JPA+Reference+Guide#JPARefer...
OGM's reference documentation recommends to add the modules depending
on which backend is being used, i.e. for CouchDB:
org.hibernate.ogm services, org.hibernate.ogm.couchdb services
See the difference? We expect people to explicitly import he couchdb module too.
We essentially expect people to use a different API - i.e. a different
classpath - depending on the storage.. that's unusual.
The traditional answer is that you should have one API, but our case
is a bit more complex so let's see the options.
I'd like to get rid of the need specify modules. I see several paths,
some less compelling:
A- consider the "couchdb" module a non-essential, power users only
API which you can only unlock by manually configuring modules.
pros: it's done :)
cons: would we agree that OGM is still compelling even without
those "options" for a majority of basic users?
B- have WildFly inject all these modules on the user's classpath
pros: consistency, no magic, everyone gets the same.
cons: Requires updates in WildFly to support new datastores. Larger
classpath? More conflict potentials? More stuff to "support" ?
C/1- have WildFly "guess" the right dependency set by looking at
additional properties.
pros: exposes the minimum but not less
cons: requires such logic to be defined in JipiJapa, needs long
term stability, needs to deal with multiple (different) PU
configurations.
C/2- have WildFly invoke some helper of ours which defines the
modulesets we want
pros: we can control and evolve this as we realise which mistakes
we're making :)
cons: more complex to define this contract?
My vote goes to B, at least for the short term. C/2 is my favourite in
the longer term, or at least a B which allows us to define new
datastores without needing changes in WildFly.
Orthogonal to this, but to keep in mind: WildFly also injects the
"main" slot exclusively. We'll need a way to pick a specific version,
or at least allow overrides like we do with Search.
Thanks,
Sanne
8 years, 7 months
[HSEARCH] Feedback on Elasticsearch presentation
by Emmanuel Bernard
Hey all,
I've done a presentation of the new Elasticsearch integration with a
Elasticsearch developer+advocate. Here are some key inputs from the
listener feedback.
The presentation was a Tools in Action (30 mins) where we took a JPA
app, added Elasticsearch for entity indexing manually (describing
issues) and then restart with Hibernate Search.
There was big interest, so a bit less feature release earlier will help
more than "better" later.
One big feedback is that we need to help people on the analyzer
definition in Elasticsearch (from our metadata):
- map existing ES analyzers to ours
- offer way to define an analyzer and have it pushed with the index
definition when we create them
- figure out a way to embed the additional key options like nbr of
shards when we create the index definition
- offer an export function for our index definition so that people can
curl it themselves
The other part was about mapping:
- support for parent child: parent / child is a bit like Infinispan
grouping where the children are colocated in the same node as the
parent. So it's a single node join. David was not necessarily
recommending me to support that from the get go because we already
handle the right denormalization via HSearch.
- support for nested mapping and nested queries. This is also a
relatively expensive prop so not all nested structure should be mapped
as ES nested. Here we probably should offer a specific mapping
annotation or option and write the nested query accordingly
For the mapping part, we probably should write these down in the FAQ as
to why we don't do them right away and the workaround available.
Emmanuel
8 years, 8 months