- This topic has 1 reply, 1 voice, and was last updated 13 years, 8 months ago by hoteagle.
-
AuthorPosts
-
hoteagleMember“Hibernate RE” in the title means Hibernate Reverse Engineer.
I just build a small demo to test the Hibernate Reverse Engineer’s results. I mostly follows the steps in the tutorial for “Hibernate & Spring” at http://www.myeclipseide.com/documentation/quickstarts/hibernateandspring/.
I changed the sample a little with two tables contains foreign key.
I find errors during just a simple queryByName search based on the generated DAO&POJO. It seems like getHibernateTemplate().find cannot correctly return a List<Entity> where Entity is a POJO generated by Hibernate Reverse Engineer.
Since Foreign key constrain is very common in DB and this might be a critical problem for Hibernate Reverse Engineering if my usage is not wrong.I bought the MyEclipse for Spring and using version 8.6 and 9.0 both on MAC os 10.6.7. I use Hibernate 3.3 and Spring 3.0 in the project below. DB used MySql (version > 5.0). No annotation used.
The detailed descriptions:
The difference is that I create two tables with a simple foreign key constrain. In the following two tables, the entity contains a ‘Type’ which is mapped as many-to-one to “etype” in table codeentitytype
DROP TABLE IF EXISTS `codeentitytype`; CREATE TABLE `codeentitytype` ( `code` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT '', `etype` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`code`), UNIQUE KEY `etype` (`etype`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; DROP TABLE IF EXISTS `entity`; CREATE TABLE `entity` ( `EntityID` int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(200) DEFAULT NULL, `Type` varchar(50) DEFAULT NULL, PRIMARY KEY (`EntityID`), KEY `Name` (`Name`), KEY `Type` (`Type`), CONSTRAINT `entity_ibfk_1` FOREIGN KEY (`Type`) REFERENCES `codeentitytype` (`etype`) ON DELETE NO ACTION ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Then I write a simple query.
// BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); ApplicationContext ctx = new ClassPathXmlApplicationContext ("applicationContext.xml"); Persistence persistenceLayer = (Persistence) ctx.getBean("persistence"); List<Entity> entLst = persistenceLayer.findEntityByName("dna1"); ListIterator<Entity> iter = entLst.listIterator(); while(iter.hasNext()){ Entity ent = iter.next(); Integer id = ent.getEntityId(); System.out.println("Find entity with name as " + name + " with id = " + id); }
Then it comes with the following errors. It seems query is done but error happens during translate the rows obtained back to POJO Class like “Entity”. The Entity class generated by Hibernate reverse engineer contains a property like “private Codeentitytype codeentitytype;” but not “String Type“, which is due to the foreign key definition.
I guess the error might due to some mismatch between the returned String like ‘DNA’ in the row found by getHibernateTemplate().find and the properties in Entity as Codeentitytype codeentitytype. Note that the first property in Class Codeentitytype is “Integer code”, which is int type.Exception in thread “main” org.springframework.dao.TransientDataAccessResourceException: Hibernate operation: could not execute query; SQL [select entity0_.EntityID as EntityID0_, entity0_.Type as Type0_, entity0_.Name as Name0_ from FKDemo.entity entity0_ where entity0_.Name=?]; Invalid value for getInt() – ‘DNA’; nested exception is java.sql.SQLException: Invalid value for getInt() – ‘DNA’
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:107)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.orm.hibernate3.HibernateAccessor.convertJdbcAccessException(HibernateAccessor.java:424)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:410)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:912)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:908)
at hibernate.EntityDAO.findByProperty(EntityDAO.java:84)
at hibernate.EntityDAO.findByName(EntityDAO.java:92)
at hibernate.Persistence.findEntityByName(Persistence.java:17)
at hibernate.Logic.main(Logic.java:25)
Caused by: java.sql.SQLException: Invalid value for getInt() – ‘DNA’
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2725)
at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2813)
at org.hibernate.type.IntegerType.get(IntegerType.java:51)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:184)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:173)
at org.hibernate.type.ManyToOneType.hydrate(ManyToOneType.java:126)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2114)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1404)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1332)
at org.hibernate.loader.Loader.getRow(Loader.java:1230)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:603)
at org.hibernate.loader.Loader.doQuery(Loader.java:724)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.doList(Loader.java:2232)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)
at org.hibernate.loader.Loader.list(Loader.java:2124)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:401)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1149)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:921)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:1)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
… 7 moreIn order to prove my guess, I faked the table a little to change the “Integer code” property to be as “String code” which is no more as “int” type. The changed table is like:
DROP TABLE IF EXISTS `codeentitytype`; CREATE TABLE `codeentitytype` ( `code` varchar(255) NOT NULL, `name` varchar(255) DEFAULT '', `etype` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`code`), UNIQUE KEY `etype` (`etype`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; DROP TABLE IF EXISTS `entity`; CREATE TABLE `entity` ( `EntityID` int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(200) DEFAULT NULL, `Type` varchar(50) DEFAULT NULL, PRIMARY KEY (`EntityID`), KEY `Name` (`Name`), KEY `Type` (`Type`), CONSTRAINT `entity_ibfk_1` FOREIGN KEY (`Type`) REFERENCES `codeentitytype` (`etype`) ON DELETE NO ACTION ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Then the original simple query codes will pass with correct result (one entity id is found and printed). However, it doesn’t mean the problem is gone. Just try to print more about the Codeentitytype type and it will report error again.
List<Entity> entLst = persistenceLayer.findEntityByName(name); ListIterator<Entity> iter = entLst.listIterator(); while(iter.hasNext()){ Entity ent = iter.next(); Integer id = ent.getEntityId(); Codeentitytype type = ent.getCodeentitytype(); System.out.println("Find entity with name as " + name + " with id = " + id + " type = " + type.getEtype() ); }
The error below shows that it might try to use the String “DNA” found within the return row to match with the “Codeentitytype” but failed.
Exception in thread “main” org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException: No row with the given identifier exists: [hibernate.Codeentitytype#DNA]; nested exception is org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [hibernate.Codeentitytype#DNA]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:663)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:912)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:908)
at hibernate.EntityDAO.findByProperty(EntityDAO.java:84)
at hibernate.EntityDAO.findByName(EntityDAO.java:92)
at hibernate.Persistence.findEntityByName(Persistence.java:17)
at hibernate.Logic.main(Logic.java:25)
Caused by: org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [hibernate.Codeentitytype#DNA]
at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:419)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:171)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:207)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:906)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:874)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:590)
at org.hibernate.type.EntityType.resolve(EntityType.java:412)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:877)
at org.hibernate.loader.Loader.doQuery(Loader.java:752)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.doList(Loader.java:2232)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)
at org.hibernate.loader.Loader.list(Loader.java:2124)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:401)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1149)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:921)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:1)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
… 7 morePlease help me on this issue. I have lots of table with some foreign keys defined and wish to depend on Hibernate’s Reverse Engineering ability to manage it.[/list]
BTW, I also tried with tables w/o foreign key and the whole story above works well. So the errors are most possibly caused by foreign key.
hoteagleMemberthis poster is wrongly repeatedly posted. Please help to delete it!
-
AuthorPosts