i recently updated from mysql-connector-java 5.1.22 to 5.1.23. After that my application is constantly crashing on update or delete of persisted objects.
Mysql Connectors up to 5.1.22 (including 5.1.22) are working fine. MySQL Connectors from 5.1.23 (including 5.1.23) are not working.
Cause of the Problem seems to be the Time stamp i use for Optimistic locking. Optimistic locking with a Version seems to work fine. But i can't change the whole application and i need the Time stamp fields.
The changelog of 5.1.23 states the following bugfix:
> If a timestamp value was passed through prepared statement parameters, > fractional-second precision was stripped off, even if the underlying > field (such as VARCHAR(255)) could store the full value. A workaround > was to convert the timestamp value to a string when specifying the > prepared statement argument, for example > prepped_stmt.setString(1,time_stamp.toString(). This was partly fixed > in 5.1.19, but that fix did not cover the case with the setting > useLegacyDatetimeCode=true. (Bug #11750017, Bug #40279, Bug #60584)
I suspect this is the cause of my problems. Any ideas how to solve the problem? I appended a simple sample code causing the error.
---Exception
Jul 02, 2014 9:18:34 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit> INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final} Jul 02, 2014 9:18:34 AM org.hibernate.Version logVersion INFO: HHH000412: Hibernate Core {4.3.5.Final} Jul 02, 2014 9:18:34 AM org.hibernate.cfg.Environment <clinit> INFO: HHH000206: hibernate.properties not found Jul 02, 2014 9:18:34 AM org.hibernate.cfg.Environment buildBytecodeProvider INFO: HHH000021: Bytecode provider name : javassist Jul 02, 2014 9:18:34 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!) Jul 02, 2014 9:18:34 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/hibernatedb?useFastDateParsing=false] Jul 02, 2014 9:18:34 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH000046: Connection properties: {user=root, password=****} Jul 02, 2014 9:18:34 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH000006: Autocommit mode: false Jul 02, 2014 9:18:34 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure INFO: HHH000115: Hibernate connection pool size: 1 (min=1) Jul 02, 2014 9:18:34 AM org.hibernate.dialect.Dialect <init> INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect Jul 02, 2014 9:18:34 AM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService INFO: HHH000399: Using default transaction strategy (direct JDBC transactions) Jul 02, 2014 9:18:34 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init> INFO: HHH000397: Using ASTQueryTranslatorFactory Jul 02, 2014 9:18:35 AM org.hibernate.tool.hbm2ddl.SchemaExport execute INFO: HHH000227: Running hbm2ddl schema export Jul 02, 2014 9:18:35 AM org.hibernate.tool.hbm2ddl.SchemaExport execute INFO: HHH000230: Schema export complete MyPersistentObject (2014-07-02 09:18:35.0) : First persistent object MyPersistentObject (2014-07-02 09:18:35.0) : A second persistent object org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [MyPersistentObject#2] at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2541) at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3403) at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3630) at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:114) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) at HibernateExample.manipulatePersistentObjects(HibernateExample.java:143) at HibernateExample.main(HibernateExample.java:15) MyPersistentObject (2014-07-02 09:18:35.0) : First persistent object MyPersistentObject (2014-07-02 09:18:35.0) : A second persistent object Jul 02, 2014 9:18:35 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost:3306/hibernatedb?useFastDateParsing=false]
---main class
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.service.ServiceRegistry; public class HibernateExample { private final org.hibernate.SessionFactory _sessionFactory; private MyPersistentObject _myPersistentObject1; private MyPersistentObject _myPersistentObject2; private MyPersistentObject _myPersistentObject3; final static public void main(final String arguments[]) { HibernateExample example; example = new HibernateExample(); example.createPersistentObjects(); example.readAndDisplayPersistentObjects(); example.manipulatePersistentObjects(); example.readAndDisplayPersistentObjects(); example.cleanup(); } private HibernateExample() { org.hibernate.cfg.Configuration configuration; java.util.logging.Logger.getLogger("org.hibernate").setLevel(java.util.logging.Level.SEVERE); // Supress // Hibernate's // excessive // output configuration = new org.hibernate.cfg.Configuration(); configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); // Customize // this // for // your // particular // RDBMS configuration.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver"); // Customize // this // for // your // particular // RDBMS // configuration.setProperty("hibernate.connection.url", // "jdbc:mysql://localhost:3306/hibernatedb?useLegacyDatetimeCode=true"); // // Customize configuration.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernatedb?useFastDateParsing=false"); // Customize // this // for // your // particular // RDBMS configuration.setProperty("hibernate.connection.username", "root"); // Customize // this // for // your // particular // RDBMS configuration.setProperty("hibernate.connection.password", "root"); // Customize // this // for // your // particular // RDBMS // installation configuration.setProperty("hibernate.connection.pool_size", "1"); // Customize // this // for // your // particular // RDBMS // installation configuration.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.internal.NoCacheProvider"); // This // is // not // ready // for // prime-time configuration.setProperty("hibernate.show_sql", "false"); // Tell // hibernate // to not // echo the // SQL configuration.setProperty("hibernate.hbm2ddl.auto", "create"); configuration.setProperty("useLegacyDatetimeCode", "true"); configuration.addAnnotatedClass(MyPersistentObject.class); // configuration.configure(); final ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings( configuration.getProperties()).build(); this._sessionFactory = configuration.buildSessionFactory(serviceRegistry); } final private void createPersistentObjects() { org.hibernate.Session session; boolean committed; org.hibernate.Transaction transaction; session = this._sessionFactory.openSession(); try { committed = false; transaction = session.beginTransaction(); try { this._myPersistentObject1 = new MyPersistentObject("First persistent object", new java.util.Date()); session.save(this._myPersistentObject1); this._myPersistentObject2 = new MyPersistentObject("A second persistent object", new java.util.Date()); session.save(this._myPersistentObject2); transaction.commit(); session.flush(); committed = true; } finally { if (!committed) { transaction.rollback(); } } } finally { session.close(); } } final private void manipulatePersistentObjects() { org.hibernate.Session session; org.hibernate.Transaction transaction; session = this._sessionFactory.openSession(); try { transaction = session.beginTransaction(); this._myPersistentObject3 = new MyPersistentObject("A third persistent object", new java.util.Date()); // session.save(this._myPersistentObject3); session.delete(this._myPersistentObject2); transaction.commit(); session.flush(); } catch (final Exception e) { e.printStackTrace(); } finally { session.close(); } } final private void readAndDisplayPersistentObjects() { org.hibernate.Session session; java.util.List<MyPersistentObject> result; session = this._sessionFactory.openSession(); try { session.beginTransaction(); result = (session.createQuery("from MyPersistentObject").list()); for (final MyPersistentObject persistentObject : result) { System.out.println("MyPersistentObject (" + persistentObject.getDate() + ") : " + persistentObject.getTitle()); } session.getTransaction().commit(); session.flush(); } catch (final Exception e) { e.printStackTrace(); } finally { session.close(); } } final private void cleanup() { if (this._sessionFactory != null) { this._sessionFactory.close(); } } }
---Object
import java.util.Calendar; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import javax.persistence.Version; @javax.persistence.Entity public class MyPersistentObject { @javax.persistence.Id @javax.persistence.GeneratedValue(generator = "increment") @org.hibernate.annotations.GenericGenerator(name = "increment", strategy = "increment") private Long _persistenceID; private String _title; @javax.persistence.Temporal(javax.persistence.TemporalType.TIMESTAMP) @javax.persistence.Column(name = "OBJECT_DATE") private java.util.Date _date; @Version private Calendar timestemp; // Hibernate needs a no-argument constructor private MyPersistentObject() { } // for application use, to create new persistent objects public MyPersistentObject(final String title, final java.util.Date date) { this._title = title; this._date = date; } public java.util.Date getDate() { return this._date; } public String getTitle() { return this._title; } @PrePersist protected void onCreate() { System.out.println("create"); } @PreUpdate protected void onUpdate() { System.out.println("update"); } }
---pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>Hibernate34Migrate</groupId> <artifactId>Hibernate34Migrate</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.5.Final</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>4.3.5.Final</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.31</version> </dependency> </dependencies> </project>
|