Hibernate 4.3 to 5.2 upgrade - cannot simultaneously fetch multiple bags - spring

Trying to upgrade to hibernate 5.2.9 from 4.3.11. Currently using the hibernate native api. After adding the dependency in pom.xml I get the following error when running my units tests:
Unsatisfied dependency expressed through field 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [testApplicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
I have a testApplicationContext.xml with the following:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="org.xxxx.xxxx.xxxx.model"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
I updated the sessionFactory and transactionManager from hibernate4 to hibernate5.
pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.9.Final</version>
</dependency>
As far as I can tell, the error message implies that there is an issue loading multiple eagerly loaded collections. However, I understand from this that using hibernate-specific annotations and newer versions of hibernate support this use case.
Can anyone help please? Thanks

This issue has been resolved now.
In a couple of my entities I was using a List for #OneToMany.
Changing to Set resulted in the error going away. Not sure as yet why this worked/was supported in Hibernate 4.3.11 and not 5.2.9. I will update this answer if I find any further information.
Further info with regard to List vs Set can be found here and here.

Related

configuring hibernate datasource in spring xml

I get below error while running my web application. I had problems in configuring hibernate & spring with right jars. After i crossed that hurdle after working on it for hours, i am getting problem in hibernate datasource. The session factory and dao beans are getting initialized properly by spring
but when i access method in dao i get error...
INFO: Attestation_spring_hibernate was successfully deployed in 11,309 milliseconds.
INFO: before calling rateDAO.getCount()
INFO: inside getSessionFactory()
WARNING: StandardWrapperValve[dispatcher]: Servlet.service() for servlet dispatcher threw exception
java.lang.UnsupportedOperationException: Not supported by BasicDataSource
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1062)
at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:141)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:292)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:214)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:157)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:56)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:161)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:182)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:159)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1859)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1836)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1816)
at org.hibernate.loader.Loader.doQuery(Loader.java:900)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
at org.hibernate.loader.Loader.doList(Loader.java:2526)
at org.hibernate.loader.Loader.doList(Loader.java:2512)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2342)
at org.hibernate.loader.Loader.list(Loader.java:2337)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:124)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1662)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
at daoImpl.RateDAO.getRateById(RateDAO.java:149)
at controller.Controller1.welcome(Controller1.java:47)
Below is my application context.xml..
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test_amar"/>
<property name="username" value="root"/>
<property name="password" value=""/>
<property name="initialSize" value="2"></property>
<property name="maxActive" value="5"></property>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<!-- Hibernate Session Factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="packagesToScan">
<array>
<value>entities</value>
</array>
</property>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
i use spring3 & hibernate4. It appears there is configuration error in my datasource. but i am not able to locate it.
From the server log below , i see that dao & session factory beans are instantiated properly.
INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
INFO: JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
INFO: JSR-330 'javax.inject.Named' annotation found and supported for component scanning
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#1020cb7: defining beans [**controller1,rateDAO**,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping#0,urlMapping,viewResolver,indexController,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory#fca094
INFO: Mapped URL path [/controller1] onto handler 'controller1'
INFO: Mapped URL path [/controller1/*] onto handler 'controller1'
Kindly assist..
Accoording to the latest version, the method getConnection(user, password) is not supported, but hibernate should not be calling that method.
You can use the spring provided org.springframework.jdbc.datasource.DriverManagerDataSource or the com.mysql.jdbc.jdbc2.optional.MysqlDataSource from your MySQL connector package. (http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html)
try to add the following code in hibernate property
<prop key=" hibernate.dialect "> org.hibernate.dialect.MySQLDialect </prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.connection.username">root</prop>
<prop key="hibernate.connection.password">root</prop>
</props>
try to remove from hibernate.cfg.xml
<property name="hibernate.connection.password">your-password</property>
<property name="hibernate.connection.username">your-username</property>
The problem with
org.springframework.jdbc.datasource.DriverManagerDataSource
is that it does NOT provides pooling! I would move to Tomcat JDBC Connection Pool. That is by now IMHO the most efficient one.
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
It requires the dependency
org.apache.tomcat tomcat-jdbc
Check documentation:
https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html
Try to use com.mysql.jdbc.jdbc2.optional.MysqlDataSource.

Issue when trying to export spring bean as OSGI service

I wanted to export a bean as a OSGi service , so that this can be used in another bundle. But I get the below error. Please help.
SEVERE: Unable to create application context for [com.abc.test.impl], unsatisfied dependencies: Dependency on [(objectClass=com.abc.platform.test.manager.ITestManager)] (from bean [&testManager])
org.springframework.context.ApplicationContextException: Application context initialization for 'com.xyz.test.impl' has timed out waiting for (objectClass=com.abc.test.manager.ITestManager)
The code is given below.
Bundle 1 (com.abc.test.impl) :
Bean declaration -
<bean id="testManagerTarget" class="com.abc.platform.test.TestManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="testManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref bean="testManagerTarget" />
</property>
<property name="transactionAttributes">
<props>
<prop key="store">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
Declaring bean as OSGI service -
Text content in the code blocks is automatically word-wrapped
<osgi:service id="testManagerService" ref="testManager" interface="com.abc.platform.test.manager.ITestManager" />
Bundle 2 (com.xyz.test.impl):
<osgi:reference id="testManager" interface="com.abc.platform.test.manager.ITestManager" />
Really appreciate any help.
Thanks
Soniya

Spring Entitymanager java.lang.ClassFormatError

This is 2nd day that I am struggling with this issue.
We have a web app that uses spring and hibernate. Now We are trying to expose some functionality to command line. So We should be able to run a class from command line(without web app) so it should have access to spring and hibernate.
<context:annotation-config/>
<context:component-scan base-package="com.x.y.z"/>
<jpa:repositories base-package="com.x.y" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="jpaProperties">
<props>
<prop key="javax.persistence.validation.mode">NONE</prop>
<prop key="hibernate.validator.apply_to_ddl">false</prop>
<prop key="hibernate.validator.autoregister_listeners">false</prop>
<prop key="hibernate.format_sql">false</prop>
</props>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="database" value="SQL_SERVER" />
<property name="showSql" value="false" />
</bean>
</property>
</bean>
Here I am using LocalEntityManagerFactoryBean but it seems there is no way to set datasource to it. It gets from persistance.xml
If I use LocalContainerEntityManagerFactoryBean I can set datasource(it has datasource property)
persistance.xml:
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="oms-jpa">
<class>com.domain.User</class>
</persistence-unit>
In persistance.xml I am not defining any database informaton for datasource, so LocalEntityManagerFactoryBean does not work for this.
what I am getting:
Error creating bean with name 'entityManagerFactory' defined in file [C:\Users\ekamoliddinov\IdeaProjects\web\conf\spring-config.xml]: Invocation of init method failed; nested exception is java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/validation/Validation
googled then some says:
Jar versions messed up
jee-api.jar is missing
But I have jee-api.jar.
My questions:
What is causing the above exception?
Can I use LocalContainerEntityManagerFactoryBean without having web
container? Spec does not say anything about this.
If i can not use LocalContainerEntityManagerFactoryBean then how can I set up
LocalEntityManagerFactoryBean so it should use my datasource not from
persistance.xml(I can not define anything in persistance.xml).
I am using spring version 3.1.3 with hibernate 4.1.8.Final and i am in command line(I do no have jee environment)
Sorry about more than one questions, but all questions are arising from the same root I think.
Any help will be appreciated.
Thanks.
After trying 3 days I fixed the issue. The jars where messed up :)
It was because I have jee-api.jar in my classpath and I was running the code from command line, I had not web env. So there was not any impl of jee-api.jar in my env. That is why it was giving the above exception. I removed jee-api.jar and disappeared.
Another thing That I can tell: we can use LocalContainerEntityManagerFactoryBean from command line. I am using it.
The last thing: We can not set datasource to LocalEntityManagerFactoryBean
This my help to someone.

JNDI does not work with HornetQ and tomcat

I'm trying running JMS application using hornetq on tomcat! I tried following this article. I put jndi.properties in my client class path; jndi.properties:
java.naming.factory.initial=org.apache.naming.java.javaURLContextFactory
java.naming.factory.url.pkgs=org.apache.naming
I added these dependencies to pom.xml:
<dependency>
<groupId>tomcat</groupId>
<artifactId>naming-factory</artifactId>
<version>5.5.23</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>tomcat</groupId>
<artifactId>naming-resources</artifactId>
<version>5.5.23</version>
<scope>test</scope>
</dependency>
My JMS spring beans:
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.apache.naming.java.javaURLContextFactory</prop>
<prop key="java.naming.factory.url.pkgs">org.apache.naming</prop>
</props>
</property>
</bean>
<!-- Connection Factory -->
<bean id="hornetqConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate"/>
<property name="jndiName" value="/ConnectionFactory" />
</bean>
<!-- Destinations -->
<bean id="annotationDeleteCommandDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate"/>
<property name="jndiName" value="/queue/command/annotation/deleteQueue" />
</bean>
I'm using HornetQ default server (standalone, non-clustered)
hornetq-jms.xml:
<queue name="annotationDeleteCommandQueue">
<entry name="/queue/command/annotation/deleteQueue"/>
</queue>
<connection-factory name="NettyConnectionFactory">
<xa>false</xa>
<connectors>
<connector-ref connector-name="netty"/>
</connectors>
<entries>
<entry name="/ConnectionFactory"/>
</entries>
</connection-factory>
But when i starting tomcat i get this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hornetqConnectionFactory' defined in ServletContext resource [/WEB-INF/classes/config/spring/applicationContext-jms.xml]:
Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name ConnectionFactory is not bound in this Context .........
What is wrong?
Should i put any jar files in the tomcat classpath? (which jars?)
Should i put queues and connection factories definitions in the tomcat configs? (how?)
Can i disable JNDI in tomcat and use hornetq standalone JNDI instead?
I solved this problem by modification of jndiTemplate (using jboss naming) and adding jnp-client.jar to client classpath:
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
<prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>
<prop key="java.naming.provider.url">jnp://localhost:1099</prop>
</props>
</property>
</bean>
Are you sur HornetQ is started correctly? The error log seems to indicate that the ConnectionFactory is not present.
Have you tried to access HornetQ using another tool?
You should be able to use JMX or HermesJMS (http://www.hermesjms.com) to verify the presence of your ConnectionFactory

'hibernate.dialect' must be set when no Connection available

I am trying to run a hello world for: Spring/Hibernate with HSQLDB and C3PO connection pool.
the same code works with mySQL (only with different dialect and driver)
I have run the database and I can connect to it with the swing GUI. But when I try to run my application, I am getting a start up error.
Here are the details:
1: the error -
INFO: Initializing Spring root WebApplicationContext
[ERROR] [pool-2-thread-1 05:20:08] (JDBCExceptionReporter.java:logExceptions:101) Connections could not be acquired from the underlying database!
[ERROR] [pool-2-thread-1 05:20:08] (ContextLoader.java:initWebApplicationContext:220) Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/hibernate-context.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: 'hibernate.dialect' must be set when no Connection avalable
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
...
...
2: hibernate-context.xml -
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.gleeb.sample.model" />
<property name="hibernateProperties">
<props>
<!-- <prop key="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> -->
<prop key="dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="show_sql">false</prop>
<prop key="hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" p:driverClass="org.hsqldb.jdbc.JDBCDriver"
p:jdbcUrl="jdbc:hsqldb:hsql://localhost/testdb" p:user="sa"
p:password="" p:acquireIncrement="5" p:idleConnectionTestPeriod="60"
p:maxPoolSize="100" p:maxStatements="50" p:minPoolSize="10" />
<!-- Declare a transaction manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
As far as I can tell, it is not possible to pass in the dialect as a value set on the hibernateProperties field of a Spring Session Factory, at least if you are also using the configLocation property on it.
My hibernate.cfg.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.DB2Dialect</property>
<property name="hibernate.search.autoregister_listeners">false</property>
[etc...]
My relevant session factory context config:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<!--<prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop>-->
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.default_schema">xxx</prop>
</props>
</property>
</bean>
If I uncomment the dialect prop in the context file, and comment it out from in the hibernate.cfg.xml file I encounter the same exception as the OP:
Caused by: org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set
However if I run with the above configuration (commented out in the context file, uncommented in the hibernate.cfg.xml), it works, and I see the formatted hibernate SQL, showing that the other hibernate properties are being set by the context file.
I have session factory properties with hibernate. prefix.
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=false
hibernate.format_sql=false
</value>
</property>

Resources