Spring & Hibernate : generate dataBase using Spring Configuration - java

I'm trying to use SchemaExport in my app to create the DB schema in my applicatione. I'm using Spring configuration file to create SessionFactory bean, but o dont know how to use SessionFactory bean to generate my Database.
spring.xml :
<context:annotation-config />
<context:component-scan base-package="com.test" />
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="com.test.model.Personne" />
</session-factory>
</hibernate-configuration>

You can use hibernate.hbm2ddl.auto configuration property to make Hibernate generate the tables according to the Hibernate mappings.
More information can be found here in the "Miscellaneous Properties" section.

Related

Spring Cfg+Hibernate Cfg and Anotations

I want to make a test with HQL but the mapping tables is with Annotations.
Hibernate configuration file is in the /WEB-INF/spring-config-ws.xml :::>
<!-- Activate transaction declarations with annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Property files application uses -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<!-- JNDI DataSource -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${dataSource.jndiName}" />
<property name="lookupOnStartup" value="false"/>
<property name="cache" value="true"/>
<property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
<property name="packagesToScan">
<list>
<value>es.sergas.rprof.profesional.domain</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.default_schema">${hibernate.default_schema}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
</props>
</property>
</bean>
<!-- Transaction manager for Hibernate SessionFactory -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
When I run a list, I get that you do not find the hibernate cfg:
hibernate.cfg.xml not found
I just want to list a mapped class with annotations, but HQL
I feel my level of English is so low. Thank you
Make sure your hibernate.cfg.xml is inside src/main/resources, if the file is not there you need to specify the right location, so put it inside this folder that your problem will be solved.
Note that we don’t have to explicitly mention the mapping or configuration or properties
files, because the Hibernate runtime looks for default filenames, such as hibernate.
cfg.xml or hibernate.properties, in the classpath and loads them. If we have a nondefault
name, make sure you pass that as an argument—like configure("my-hibcfg.
xml"), for example.

Multiple persistence unit in persistence.xml file with JPA 2.1

I am trying to deploy an application that connects to Oracle Database and MySQL. I am using JPA 2.1, Hibernate 4.3.7, Spring, Spring Data and WildFly 8.2 but I am getting some errors when deploying the application. Eclipse shows error. He says that I cannot use more than one persistence unit. I was confused because I found some articles on the web showing files with more than one persistence unit. Like this one.
First of all my persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="authwsPU" transaction-type="JTA">
<jta-data-source>java:/datasource/authwsds</jta-data-source>
..My MySQL mapping classes...
<properties>
<!-- MySQL -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.id.new_generator_mappings" value="true"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:jboss/authwsEMF" />
</properties>
</persistence-unit>
<persistence-unit name="antaresPU" transaction-type="JTA">
<jta-data-source>java:/datasource/antaresds</jta-data-source>
...My Oracle mapping classes...
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.id.new_generator_mappings" value="true"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:jboss/antaresEMF" />
</properties>
</persistence-unit>
</persistence>
I made change on jboss-web.xml too:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee
http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
<context-root>/authws</context-root>
<persistence-context-ref id="autenticacaoCtx">
<persistence-context-ref-name>auth_ws/authEMF</persistence-context-ref-name>
<persistence-unit-name>authwsPU</persistence-unit-name>
</persistence-context-ref>
<persistence-context-ref id="antaresCtx">
<persistence-context-ref-name>auth_ws/antaresEMF</persistence-context-ref-name>
<persistence-unit-name>antaresPU</persistence-unit-name>
</persistence-context-ref>
</jboss-web>
And the errors. Eclipse, warned me, but I ignored.:
Multiple persistence units defined - only the first persistence unit will be recognized
Then I deployed and WildFly shows this error:
Caused by: java.lang.IllegalArgumentException: JBAS011470: Persistence unitName was not specified and there are 2 persistence unit definitions in application deployment deployment "authws.war". Either change the application deployment to have only one persistence unit definition or specify the unitName for each reference to a persistence unit.
at org.jboss.as.jpa.container.PersistenceUnitSearch.ambiguousPUError(PersistenceUnitSearch.java:187)
at org.jboss.as.jpa.container.PersistenceUnitSearch.findWithinDeployment(PersistenceUnitSearch.java:153)
at org.jboss.as.jpa.container.PersistenceUnitSearch.findPersistenceUnitSupplier(PersistenceUnitSearch.java:75)
at org.jboss.as.jpa.container.PersistenceUnitSearch.resolvePersistenceUnitSupplier(PersistenceUnitSearch.java:64)
at org.jboss.as.jpa.processor.JPAAnnotationProcessor.getPersistenceUnit(JPAAnnotationProcessor.java:372)
at org.jboss.as.jpa.processor.JPAAnnotationProcessor.getBindingSource(JPAAnnotationProcessor.java:296)
at org.jboss.as.jpa.processor.JPAAnnotationProcessor.processMethod(JPAAnnotationProcessor.java:206)
at org.jboss.as.jpa.processor.JPAAnnotationProcessor.processPersistenceAnnotations(JPAAnnotationProcessor.java:143)
at org.jboss.as.jpa.processor.JPAAnnotationProcessor.deploy(JPAAnnotationProcessor.java:100)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:159) [wildfly-server-8.2.0.Final.jar:8.2.0.Final]
... 5 more
UPDATE
I am updating the question with more details. First, the file where I create the EntityManagersFactory for Spring Data:
<jee:jndi-lookup jndi-name="java:jboss/poEMF" id="poEntityManagerFactory" expected-type="javax.persistence.EntityManagerFactory" />
<jpa:repositories base-package="br.com.po.dao" entity-manager-factory-ref="poEntityManagerFactory" />
<jee:jndi-lookup jndi-name="java:jboss/antaresEMF" id="antaresEntityManagerFactory" expected-type="javax.persistence.EntityManagerFactory" />
<jpa:repositories base-package="br.com.antares.dao" entity-manager-factory-ref="antaresEntityManagerFactory" />
Reading more about this online, I saw that the problem can be specification of the annotation #PersistenceUnit where I have to specify the unitName like #PersistenceUnit(unitName="defaultPersistenceUnit"). But, how I do this if I am using Spring Data?
For example you can use #EnableJpaRepositories in your #Configuration files (if you are using Bean Configuration) like this:
One configuration file with:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
basePackages = {"com.yourpackage.xxxx"},
entityManagerFactoryRef = "entityManagerFactory1",
transactionManagerRef = "transactionManager")
public class FirstPersistenceContextConfig {}
....
And a second configuration file:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
basePackages = {"com.yourpackage.yyyy"},
entityManagerFactoryRef = "entityManagerFactory2",
transactionManagerRef = "transactionManager")
public class SecondPersistenceContextConfig {}
...
I don't know if you've solved your problem.
If you're using a XML configuration, try this:
<jpa:repositories base-package="[repository]"
entity-manager-factory-ref="mysqlManager" transaction-manager-ref="mysqlTransaction"/>
<jpa:repositories base-package="[repository]"
entity-manager-factory-ref="oracleManager" transaction-manager-ref="oracleTransaction"/>
<bean id="mysqlDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- MySQL Configuration Connection -->
</bean>
<bean id="mysqlTransaction" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="mysqlManager" />
</bean>
<bean id="mysqlManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mysqlDataSource" />
<property name="persistenceUnitName" value="mysqlPU" />
<property name="packagesToScan" value="lh.ast.model" />
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- Oracle Configuration Connection -->
</bean>
<bean id="oracleTransaction" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="oracleManager" />
</bean>
<bean id="oracleManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="oracleDataSource" />
<property name="persistenceUnitName" value="oraclePU" />
<property name="packagesToScan" value="[your entity package]" />
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>

Configuring Spring + Hibernate JPA Transaction Manager through JTA

I previously had this config for Hibernate using RESOURCE-LOCAL transaction type:
persistence.xml:
<persistence-unit name="myPU" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
</persistence-unit>
applicationContext (dataaccess bit):
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"></bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="persistenceUnitName" value="myPU"/>
<property name="jpaProperties">
<props>
<prop key="javax.persistence.validation.mode">none</prop>
</props>
</property>
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<!-- Are there any other properties required? -->
</bean>
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/CNTXESDB" />
<property name="lookupOnStartup" value="true" />
<property name="cache" value="true" />
<property name="proxyInterface" value="javax.sql.DataSource" />
</bean>
But this kind of transaction seems not to work with Glassfish, so I had to switch to JTA transactions.
The problem is -- to get Spring to manage transaction creation (through #Transactional) I need to define a TransactionManager bean but JtaTransactionManager included in spring-tx does not accept an entityManagerFactory bean, so it does not know where the entityManager is in order to open/close/flush Hibernate session.
So how can I configure Spring with Hibernate to use JTA transactions?
EDIT:
turns out you can use RESOURCE_LOCAL transactions with Glassfish, but somehow you cannot have a persistence.xml file. I renamed this file to my_persistence.xml and configured LocalContainerEntityManagerFactoryBean like this:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="persistenceUnitName" value="myPU"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/my_persistence.xml" />
<property name="jpaProperties">
<props>
<prop key="javax.persistence.validation.mode">none</prop>
</props>
</property>
</bean>
I had a similar problem and finally I solved as you can see in this little demo:
https://github.com/miguelangelprogramacion/spring4_jpa_hibernate
With [1] as a reference, I prefer to use Spring's Transaction Support before JTA.
Also, I've used an annotation based approach.
[1] http://spring.io/blog/2011/08/15/configuring-spring-and-jta-without-full-java-ee/

Configure hibernate in spring application

I have successfully configured hibernate and I can run transactions but only from the psvm of the DAO class. I want to configure it with my spring app using the same configuration file i.e. hibernate.cfg.xml.
How can I do this? Most tutorials I've read simply neglect the hibernate configuration file.
You can add this code to you xml file to configure hibernate.
<!-- Hibernate Related Configuration. -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://192.168.1.9:5432/dbname"/>
<property name="username" value="postgres"/>
<property name="password" value="pwd"/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.domain"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<!-- Transaction Manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
The hibernate.cfg.xml file is specified for the LocalEntityManagerFactoryBean, along with your DataSource
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/hibernate.cfg.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
Here you can find an example of a Spring XML configuration containing some Hibernate configuration

Getting save is not valid without active transaction error on using transaction annotation

I'm using spring + hibernate + jersey in my application. I want to use transactions so I used spring's #Transactional annotation in my service layer. This is my hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/db</property>
<property name="hibernate.connection.username">user</property>
</session-factory>
</hibernate-configuration>
I haven't used session_context here so spring can manage it. In my applicationCOntext.xml, I have defined transactionManager:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db"/>
<property name="user" value="username"/>
</bean>
<context:annotation-config/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="packagesToScan">
<list>
<value>com.hibernate.pojos</value>
</list>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
All urls matching /api/v1/* map to a servlet named jersey and servlet class used is com.sun.jersey.spi.spring.container.servlet.SpringServlet to which I have passed com.services as package to scan. In this package I have a class:
#Path("/app")
#Component
public class testApi() {
#Autowired
private DAOImpl daoimpl;
#POST
#Path("/create")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Transactional(rollbackFor = {Exception.class})
public Map<String,Object> testHello(user u) {
Map response = daoimpl.save(u);
return response;
}
}
The class daoimpl has the sessionFactory autowired and uses sessionFactory.getCurrentSession() method to get session. The method daoimpl.save(obj) just saves it in db. Since I have marked testHello as transactional, I expect a transaction to begin which is managed by spring and then control should go to daoimpl where the actual save happens. But I get save is not valid without active transaction. I have seen lot of posts where session_context is mentioned in hibernate config and because of that, spring is unable to handle transactions. But in my case, I have ensured that I dont provide any session_context. What am I missing? I even tried adding #transactional to DAO since in my sample app, Im just issuing one DB call for a service. But this didnt work either.
Well could be that you are specifying a session factory via hibernate.cfg.xml and then again in Spring which gets passed to the transaction manager.
Not sure to be honest however I have never used a hibenate.cfg.xml and then following works for me (with the transactional config added as you have specified). This also gives you the advantage of specifying your connection params as properties and allowing you to easily swap db configs via Spring Profiles or some other mechanism.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>uk.co.xyz.domain</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">${hibernate.showsql}</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.ddlauto}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.enablecache}</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
</beans>
See also here which actually suggests is shouldn't matter:
applicationContext.xml with datasource or hibernate.cfg.xml. Difference?

Categories