Git Product home page Git Product logo

Comments (16)

tazmaniax avatar tazmaniax commented on July 3, 2024 5

@asolntsev ok after doing some more digging I've found that the behaviour change in 5.x is not compatible with MySQL autoincrement and is explained in detail in this blog article. The author also raised a Hibernate JIRA ticket but by the sounds of it it has been rejected by the core Hibernate team for reasons unknown. The initial suggested work around is to add generator="native" to the @GeneratedValue definition, but I don't think it's feasible to make this change to the framework in a generic way that works for all cases. There is another suggested work around by the same author that involves using JPA XML metadata to override the annotation but that seems pretty heavy weight solution.

In the end I think will just stick with hibernate.id.new_generator_mappings=false. Apart from the id generator which is not needed in my case I don't think there is any other impact to the Hibernate execution and I don't need to support multiple database types requiring portable metadata.

Sorry for the distraction but maybe this is useful for someone else who comes across this :)

from play1.

asolntsev avatar asolntsev commented on July 3, 2024 2

@tomparle @xael-fry
I found the answer. We just have to add the following property: properties.put("org.hibernate.flushMode", FlushMode.MANUAL);

to avoid auto-saving of dirty (unsaved) objects.

from play1.

flybyray avatar flybyray commented on July 3, 2024 2

@asolntsev HibernateInterceptor is some essential part of Play! JPA improvment. I think you will need it even in Hibernate 5+. Please look for the willBeSaved variable and its usage saveAndCascade.

Maybe you should look into framework/patches/hibernate-4.2.19-patch-play.patch.patch too to find an answer for failing tests.

from play1.

xael-fry avatar xael-fry commented on July 3, 2024 1

I agree with @flybyray we should keep HibernateInterceptor

from play1.

tazabreu avatar tazabreu commented on July 3, 2024 1

@tazmaniax it was, thanks for the explanation!

from play1.

tomparle avatar tomparle commented on July 3, 2024

Thank you Andrei for this (among several others) improvement !

from play1.

asolntsev avatar asolntsev commented on July 3, 2024

@tomparle @xael-fry
Hi! Can you help me with Hibernate 5?

Can anyone tell why the third line saves BLUP, thought I didn't call any save method?

Horse existing = Horse.all().first();   // existing.bulp == null
existing.setBlup(new BLUP());
em().flush();   // why it executes "insert into BLUP (id, total) values (null, ?)" ???

from play1.

flybyray avatar flybyray commented on July 3, 2024

@asolntsev maybe it should be fixed in current play to?

https://github.com/playframework/play1/blob/master/framework/src/play/db/jpa/JPA.java#L364

The key-pattern for properties should honor org.hibernate
https://github.com/playframework/play1/blob/master/framework/src/play/db/Configuration.java#L88

thx

from play1.

flybyray avatar flybyray commented on July 3, 2024

@xael-fry @asolntsev

I found the answer. We just have to add the following property: properties.put("org.hibernate.flushMode", FlushMode.MANUAL);

It should have a ticket in lighthouse and should be fixed for 1.4.x too. The current AUTO-FlushMode has unpredictable consequences.

from play1.

asolntsev avatar asolntsev commented on July 3, 2024

@flybyray @tomparle @xael-fry Actually I am not sure about my previous answer. Probably the default value AUTO of setting "org.hibernate.flushMode" is good.

Alex, do you know why HibernateInterceptor is needed? Can we remove it? Without it, the failing test JPASave becomes green.

from play1.

asolntsev avatar asolntsev commented on July 3, 2024

Implemented in PR #1114

from play1.

tazmaniax avatar tazmaniax commented on July 3, 2024

Just testing my application with the new Hibernate 5.2.x support and I run into this exception below with my existing MySQL database.

I fixed the exception by adding this property "hibernate.id.new_generator_mappings=false" to the application.conf as suggested by the best answer in this StackOverflow entry, "Hibernate-sequence doesn't exist"

Looks like this could be a common situation and maybe this property should be included in the default application.conf. wdyt?

23:26:46,440 [play-thread-1] DEBUG ~ select next_val as id_val from hibernate_sequence for update
23:26:46,446 [play-thread-1] ERROR ~ could not read a hi value
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'mydb.hibernate_sequence' doesn't exist
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
	at com.mysql.jdbc.Util.getInstance(Util.java:408)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2490)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1858)
	at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1966)
	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:353)
	at org.hibernate.id.enhanced.TableStructure.executeQuery(TableStructure.java:216)
	at org.hibernate.id.enhanced.TableStructure.access$300(TableStructure.java:46)
	at org.hibernate.id.enhanced.TableStructure$1$1.execute(TableStructure.java:138)
	at org.hibernate.id.enhanced.TableStructure$1$1.execute(TableStructure.java:126)
	at org.hibernate.jdbc.WorkExecutor.executeReturningWork(WorkExecutor.java:55)
	at org.hibernate.jdbc.AbstractReturningWork.accept(AbstractReturningWork.java:34)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:57)
	at org.hibernate.id.enhanced.TableStructure$1.getNextValue(TableStructure.java:125)
	at org.hibernate.id.enhanced.NoopOptimizer.generate(NoopOptimizer.java:40)
	at org.hibernate.id.enhanced.SequenceStyleGenerator.generate(SequenceStyleGenerator.java:432)
	at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:105)
	at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67)
	at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189)
	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132)
	at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:840)
	at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:833)
	at org.hibernate.engine.spi.CascadingActions$8.cascade(CascadingActions.java:341)
	at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:458)
	at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:383)
	at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:193)
	at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:491)
	at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:423)
	at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:386)
	at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:193)
	at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:126)
	at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:172)
	at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:163)
	at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:74)
	at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
	at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1435)
	at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1421)
	at play.db.jpa.JPABase._save(JPABase.java:58)
	at play.db.jpa.GenericModel.save(GenericModel.java:364)
	at controllers.TaskController.addHelper(TaskController.java:452)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:538)
	at play.mvc.ActionInvoker.invoke(ActionInvoker.java:475)
	at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:469)
	at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:436)
	at play.mvc.ActionInvoker.invoke(ActionInvoker.java:159)
	at play.server.PlayHandler$NettyInvocation.execute(PlayHandler.java:326)
	at play.Invoker$Invocation$1.apply(Invoker.java:319)
	at play.Invoker$Invocation$1.apply(Invoker.java:315)
	at play.db.jpa.JPA.withTransaction(JPA.java:285)
	at play.db.jpa.JPA.withinFilter(JPA.java:238)
	at play.db.jpa.JPAPlugin$TransactionalFilter.withinFilter(JPAPlugin.java:304)
	at play.Invoker$Invocation.withinFilter(Invoker.java:298)
	at play.Invoker$Invocation.run(Invoker.java:315)
	at play.server.PlayHandler$NettyInvocation.run(PlayHandler.java:303)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
23:26:46,447 [play-thread-1] WARN  ~ SQL Error: 1146, SQLState: 42S02
23:26:46,448 [play-thread-1] ERROR ~ Table 'mydb.hibernate_sequence' doesn't exist
23:26:46,483 [play-thread-1] ERROR ~ 

from play1.

asolntsev avatar asolntsev commented on July 3, 2024

Yes, this is because hibernate.id.new_generator_mappings=false was default in Hibernate4, but in Hibernate5 default value is hibernate.id.new_generator_mappings=true`.

At the beginning I also got similar errors and added this setting. But later I discovered that there is a better solution. I re-configured my DB to properly use autoincrement.

In your case, you use MySql which supports autoincrement feature. So you probably need to turn ``autoincrementtoON` and avoid using sequences at all.

from play1.

tazmaniax avatar tazmaniax commented on July 3, 2024

@asolntsev I've been using MySQL's auto increment feature from the beginning. I think the use of sequences is being activated by the combination of the @GeneratedValue annotation on Model.id and hibernate.id.new_generator_mappings=true. The default GenerationType is auto which "Indicates that the persistence provider should pick an appropriate strategy for the particular database". As MySQL auto increment is typically the default I would be surprised if the MySQL persistence provider would select sequences for identity columns but if that is case then I think that the hibernate.id.new_generator_mappings setting is the only option in my case unless the @GeneratedValue can be removed from Model.id

from play1.

asolntsev avatar asolntsev commented on July 3, 2024

@tazmaniax So, what you suggest?

from play1.

asolntsev avatar asolntsev commented on July 3, 2024

@tazmaniax Yes, sure, it can be useful for many people.
Thank you for sharing the knowledge!

from play1.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.