Why is "annotatedClasses" needed if there is #Entity? - spring

Hello I'm building spring-hibernate application. Do i realy need configuration from below ?
<property name="annotatedClasses">
<list>
<value>org.fixus.springer.model.User</value>
</list>
</property>
I've set annotation-driven in my root-context.xml
<mvc:annotation-driven />
<context:component-scan base-package="org.fixus.springer" />
<context:component-scan base-package="org.fixus.springer.model" />
Now shouldn't hibernate automaticly take everything from this packages with annotation #Entity and convert it to table ? As for now without annotatedClasses he won't create a table from a entity

Use the docs, Luke!
[...]Example for an AnnotationSessionFactoryBean bean definition:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>test.package.Foo</value>
<value>test.package.Bar</value>
</list>
</property>
</bean>
Or when using classpath scanning for autodetection of entity classes:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="test.package"/>
</bean>
As you can see you have a choice between defining all classes explicitly or only the package for scanning. <context:component-scan/> does not recognize Hibernate/JPA annotations and hence has no effect.

Related

spring bean optional property

I am using a data source defined in tomcat in my spring configuration as shown in the below xml.
It can happen sometimes that this data source may not be defined in the context.xml of tomcat.
In such cases , the context initialization fails since myDS is not found.
Is it possible to configure the datasource as optional so that application initialisation is not impacted ?
There can be a run time error when this data source is accessed , which is acceptable
<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/myDS"/>
</bean>
<bean id="myEntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="packagesToScan" value="com..XX.XX" />
<property name="persistenceUnitName" value="myPU" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="#{systemProperties['showSql'] == null ? 'true' : systemProperties['showSql'] }" />
</bean>
</property>
<property name="persistenceUnitPostProcessors">
<list>
<ref bean="wrkflw-punitpostprocessor" />
</list>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">#{systemProperties['dbDialect']}</prop>
</props>
</property>
</bean>
Thanks
Muhad
You may check the DelegatingDataSource, you could encapsulate the logic to load the datasource from JNDI within its instantiation. For your application there will be always a DataSource there, but in some cases (whenever its not able to load the DataSource from JNDI) there is no delegation.

Spring - two persistence units with different JPA providers

Is it possible to have two persistence units, one with Hibernate to work with some entities and another with EclipseLink to work with other entities in Spring framework?
The following should work:
<bean id="schema1EM" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
...
</bean>
</property>
<property name="packagesToScan" value="org.example.domain.schema1"/>
</bean>
<bean id="schema2EM" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
...
</bean>
</property>
<property name="packagesToScan" value="org.example.domain.schema2"/>
</bean>
<jpa:repositories base-package="org.example.data.schema1" entity-manager-factory-ref="schema1EM"/>
<jpa:repositories base-package="org.example.data.schema2" entity-manager-factory-ref="schema2EM"/>
schema1EM will be assigned to all repositories declared under the package org.example.data.schema1 and schema2EM will be assigned to those under org.example.data.schema2. You will have to segregated the domain classes and repository interfaces by packages so that the Spring auto-wiring can work.

Spring+ Hibernate :How to map single session factory in multiple modules (deployed as jar)

I am working on Spring + Struts2 and Hibernate currently, My requirement is :
I have Master module which will make DB connection, shared by all other modules (deployed as Jar) in the system.
All Module specific .hbm and persistence classes will exists in Module itself
So for example My master module will have Hibernate connection file (through spring) will all .hbm mapping files, Below is the sample of Hibernate connection made through Spring.
<bean id="dataSourceErik" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="testWhileIdle" value="true" />
<property name="minEvictableIdleTimeMillis" value="120000" />
<property name="timeBetweenEvictionRunsMillis" value="30000" />
</bean>
<bean id="sessionFactoryErik"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceErik" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.generate_statistics=true
hibernate.show_sql=false
hibernate.jdbc.batch_size=10
hibernate.bytecode.use_reflection_optimizer=true
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
net.sf.ehcache.configurationResourceName=configuration/ehcache.xml
</value>
</property>
<property name="mappingLocations">
<list>
<value>classpath:configuration/hibernate/Abc.hbm.xml</value>
<value>classpath:configuration/hibernate/Xyz.hbm.xml</value>
</list>
</property>
</bean>
<bean id="AbcActionDAO" class="au.com.master.persistance.dao.AbcDbSession">
<constructor-arg ref="sessionFactoryErik" />
</bean>
<bean id="XyzActionTypeDAO"class="au.com.master.persistance.dao.XyzDbSession">
<constructor-arg ref="sessionFactoryErik" />
</bean>
if i add below code in above xml i can access '''sessionFactory''' and can connect with the DB. as i am giving the path of deployed subModule jar file, see below code :
<property name="mappingJarLocations">
<list>
<value>WEB-INF/lib/subModule.jar</value>
</list>
</property>
All above .hbm and DAO/DbSession classes exists in Master module. Now i want to use this '''sessionFactoryErik''' in my Sub modules deployed as jar. so for that i created another xml file in Sub module which will take reference of above '''sessionFactoryErik''' and will have mappings of this module specific .hbm and DAO/DbSession. Refer below code:
<bean id="sessionFactoryMonitor" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="sessionFactoryErik" ref="sessionFactoryErik" />
<property name="mappingLocations">
<list>
<value>classpath:configuration/hibernate/DDDType.hbm.xml</value>
</list>
</property>
</bean>
<bean id="testActionDAO" class="au.com.java.subModule.persistance.dao.DddActionDbSession">
<constructor-arg ref="sessionFactoryMonitor" />
</bean>
if i deployed the project and reboot the server i am getting below error.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactoryMonitor' defined in URL [jar:file:/home/developer/Project/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/webapps/erik/WEB-INF/lib/erik-monitor-1.0-SNAPSHOT.jar!/configuration/spring-monitor-dao.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'sessionFactoryErik' of bean class [org.springframework.orm.hibernate4.LocalSessionFactoryBean]: Bean property 'sessionFactoryErik' is not writable or has an invalid setter method.
Can anyone help me for this. How can i get the same session object in sub module as only Master module can make connection as it will not have any knowledge of its deployed (deployed as jar) module.
Thanks.
Tapan
the class org.springframework.orm.hibernate4.LocalSessionFactoryBean doesn't have a property called sessionFactoryErik. I am guessing that you are injecting your datasource to LocalSessionFactoryBean. if so Change this
<bean id="sessionFactoryMonitor" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="sessionFactoryErik" ref="sessionFactoryErik" />
<property name="mappingLocations">
<list>
<value>classpath:configuration/hibernate/DDDType.hbm.xml</value>
</list>
</property>
</bean>
to this
<bean id="sessionFactoryMonitor" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="sessionFactoryErik" />
<property name="mappingLocations">
<list>
<value>classpath:configuration/hibernate/DDDType.hbm.xml</value>
</list>
</property>
</bean>
sessionFactoryErik bean returns org.hibernate.internal.SessionFactoryImpl object,
so you should specify org.hibernate.internal.SessionFactoryImpl or its super class
(SessionFactory) type in au.com.master.persistance.dao.XyzDbSession constructor
reference.

Spring JPA Hibernate valid configuration not working with JdbcTemplate?

I do have a working configuration in Spring for JPA with Hibernate provider:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<tx:annotation-driven mode="aspectj"/>
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"/>
This configuration is working in a small Spring based web-app.
But, when I insert the same configuration into an other existing Spring based web-app, I do get the following exception:
javax.persistence.TransactionRequiredException: no transaction is in progress
I think it has some conflict with Spring JDBC Templates:
<bean id="mysqlTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
How can I get this to work side by side?
"no transaction in progress" just means you're trying to use an EntityManager somewhere and you didn't start a transaction first. The stack trace will tell you exactly where that is. Since you're using annotation-driven transactions, just make sure you have an appropriate #Transactional somewhere up the call chain from the location where the exception is happening.

How can i get a Spring managed SessionCustomizer into the EclipseLink Config

I'm working with eclipselink in a spring project. one necessary part of my configuration is a SessionCustomizer that configures my id-generator (Snowflake by twitter).
Is it possible to handle the creation of this customizer with spring so i can use dependency injection and use property-placeholders?
The only examples i found for Customizers always configure the class in the persistence xml.
Here is my config so far:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="platform.auth-service" />
<property name="jpaDialect" ref="jpaDialect" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaPropertyMap" ref="jPAPropertyProviderMap" />
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="generateDdl" value="${database.generateTables}" />
<property name="databasePlatform" value="${database.platform}" />
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
While the #Configurable Annotation from spring-aop (AspectJ integration) would have been a solution i decided to solve my problem with a static SequenceHolder class where i store the sequences with a SequenceInstaller bean.
Finally the SessionCustomizer installs the stored sequences in the persistencecontextfactory.
I had to configure a dependency between the factory and the installer because spring might have handled the factory before the installer otherwise.

Resources