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] 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
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
Jackson vs Gson
by Sanne Grinovero
I'm wondering why the Elasticsearch client for Hibernate Search is
using Gson, and not Jackson as JSON codec?
Especially as we already have Jackson as a dependency for both Search
(via Avro), OGM (via Couchbase), and it's also used within WildFly and
Camel, we might need to change this.
Sorry if I forgot the reasons, I vaguely remember this came up but I
couldn't find it on the list.
Thanks,
Sanne
8 years, 8 months
hibernate and transaction using method annotation
by Bhuvan Gupta
Hello All,
Link to question and discussion:
http://stackoverflow.com/questions/36920695/hibernate-and-transaction-usi...
Below i have pasted whats in the link:
Help/suggestion/advise/data points is really appreciated.
Thanks in Advance:
------------------------------------------
Firstly, I have given few data points.
Next will be the problem described.
------------------------------
*DATA POINTS:*
*[D1]* In Hibernate and Annotation and managed objects world, what i have
seen a common pattern like
@Transactionalpublic void createStuff(..){// get entity manager and
call persist and other operatation}@Transactionalpublic SomeDtoObject
getStuff(..){// get entity manager and call find and getter to
polulate a object to return}
In managed beans the Hibernate transaction is started and commited when we
call this methods.
Hibernate doc says (link
<https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/transactions.html>
):
The most common pattern in a multi-user client/server application is
session-per-request.
*[D2]* Also it is advised that connection to database should be pooled
using connection pool library C3P0 as stated on postgres documentation (link
<https://jdbc.postgresql.org/documentation/91/thread.html>):
Pg will usually complete the same 10,000 transactions faster by doing them
5, 10 or 20 at a time than by doing them 500 at a time.
*[D3]* Also with JDBC
*Given a single connection we can run one transaction at a time and as many
statement as we like within that transaction.Its upto the application(C3P0)
to make sure that two different thread executing two different
transactional method should not use same connection and one should wait
before calling the other method .*
------------------------------
*Problem:*
Now if we use the managed bean transaction pattern using annotation along
with a connection pool(*Let say only with 1 connection*) with hibernate and
session-per-request
Also let say the code is something like
@Transactionalpublic SomeDtoObject getStuff(..){// get entity manager
and call find and getter to polulate a object to returnSomeEntity se =
entityManager.find(someentity, primaryKey);//create Dtos// access
someEntity to all over this method to create SomeDtoObject that we
have to return.// also may access some file on system to fetch some
data is order to populate someDtoObject.// overall let say the method
take 150 milli second to do all its work}
Now imagine there are two different thread(T1, T2) called for getStuff(...)
T1 will enter the method and will acquire jdbc connection from connection
pool.
And when T2 will reach entityManager.find the C3P0 will check that there is
no connection left it will put T2 on hold till T1 complete the execution
which will take around 150 milli second.
Ideally, Given that getStuff(...) is going to do read only querys, both
thread can use same connection and dont hold thread from executing queries.
In above case we are keep that connection idle and also keeping the thread
to wait.
*MAIN QUESTION*
*Is there a way i can say to hibernate that a particular hibernate
transaction is readonly and hibernate can then reuse an already acquired
connection instead of asking for a new connection from the connection pool
?*
------------------------------
*Few solution found/suggested:(not convincing)*
1
<https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/transactions.html>
If
you are so much worried, dont use transaction using annotation, use
hibernate session yourself..... no i like that pattern :)
2 <https://jdbc.postgresql.org/documentation/91/thread.html> Hibernate
provide a ConnectionReleaselink
<https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/transactions.h...>
option
which can be set to after_statement.
*First* Hibernate C3P0 connection pool provider does not support
after_statement.
*Second* it will be a overhead just release and reacquire a connection.
8 years, 8 months
Usage of static fields throughout Hibernate Core
by Vlad Mihalcea
Hi,
While reviewing this PR:
https://github.com/hibernate/hibernate-orm/pull/1198/files
I realized that we have some static fields which might cause some problems
when we deploy two or more SessionFactories in the same container (e.g.
Spring).
The fix suggests that we should use synchronised, as indicated by Sonar,
but I think we should avoid the static fields altogether.
Every instance variable must be confined to an object that's confined to
the same SessionFactory root object.
Without static fields, we can make sure that nothing escapes a given
SessionFactory.
Let me know what you think.
Vlad
8 years, 8 months
Community newsletter contribution
by Vlad Mihalcea
Hi,
I wanted to ask everyone to let me know if you'd like to include any
resource in the Community newsletter.
If you stumble on a blog post, forum or StackOverflow question, that you
happened to like and was worth sharing, you can send it to me, and I'll
include it in the next edition.
Thanks,
Vlad
8 years, 8 months