JPA spring #Transaction autocommit - java

I am using spring-data-jpa with oracle. I am unable to get #Transactional to rollback by default for runtime exception.
Here are snippets:
<persistence-unit name="dev2db" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class, hbm"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:#host:port" />
<property name="javax.persistence.jdbc.user" value="loginid" />
<property name="javax.persistence.jdbc.password" value="mypass" />
</properties>
</persistence-unit>
transactional method uses import javax.transaction.Transactional;
#Transactional
public void uploadPanelAndAPK(String pz, byte[] file, String apk, byte[] fileApk, byte[] icon) {
uploadPanel(pz, file);
uploadApk(apk, fileApk, icon);
}
if uploadApk fails uploadPanel is not doing rollback.
beans context.xml snippet:
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager"/>
<jpa:repositories base-package="com.myco.dao" />
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceUnitName="dev2db">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="panelbo" class="com.myco.bo.PanelServiceSpringData"/>
Regards,
Miten.

javax.transaction.Transactional isn't (yet) supported. Use either javax.ejb.TransactionAttribute or org.springframewor.transaction.annotation.Transactional.

Related

Configure JBOSS 7.1 to use application-managed entity manager as opposed to container-managed entity manager

I am trying to upgrade my application deployment from Jboss 6.4 to Jboss 7.1 and I've not been able to get past this error:
java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named 'entityManagerFactory' in deployment ***.war for injection point private javax.persistence.EntityManager com.***.persistenceManager"}}}}}}}}
I have entityManagerFactory defined as a bean in Spring's applicationContext.xml file as shown below:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="extiPU" />
<property name="dataSource" ref="dataSource" />
<property name="jtaDataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<!--<property name="database" value="ORACLE" />-->
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.OraclePlatform" />
<property name="generateDdl" value="true" />
</bean>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
</property>
</bean>
and the content of my persistence.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="extiPU"
transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/tdsrc</jta-data-source>
<properties>
<property name="eclipselink.logging.level" value="OFF" />
<!--
<property name="eclipselink.deploy-on-startup" value="true" />
<property name="eclipselink.target-server" value="JBoss"/>
-->
<property name="eclipselink.logging.level.sql" value="OFF" />
<property name="eclipselink.logging.parameters" value="false" />
<property name="eclipselink.logging.connection" value="false" />
<property name="eclipselink.logging.session" value="false" />
<property name="eclipselink.target-database" value="Oracle" />
<property name="eclipselink.weaving" value="false" />
<property name="jboss.as.jpa.managed" value="false" />
</properties>
</persistence-unit>
In my persistence classes, I inject it by doing:
#PersistenceContext(unitName = "entityManagerFactory")
private EntityManager persistenceManager;
With all these done, I still cannot figure out why Jboss 7.1 does not allow the persistence manager to be application managed.
Thanks

Defining a jta Datasource outside of the container

Our application currently uses a datasource which is defined in the JBoss standalone.xml, and basically we need to have this be defined within the app rather than in the container for a while. Our current setup is;
application-context.xml;
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="rtsPersistenceUnit" />
<property name="packagesToScan">
...
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect"/>
</bean>
</property>
</bean>
persistance.xml:
<persistence 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_2_0.xsd"
version="2.0">
<persistence-unit name="rtsPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/jdbc/RTSdb</jta-data-source>
<class>...</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.transaction.flush_before_completion" value="true" />
</properties>
</persistence-unit>
</persistence>
datasource.xml:
<bean id="rtsDatasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="..."/>
<property name="username" value="..."/>
<property name="password" value="..."/>
</bean>
Basically all I want is for the line
<jta-data-source>java:/jdbc/RTSdb</jta-data-source>
to read from datasource.xml rather than go the container (JBoss).
It seems like it would be simple but after reading some Spring and Oracle docs I couldn't find an answer.
Yes, you could use a JTA compliant transaction manager like Atomikos or Bitronix. Their respective sites have documentation on how to configure them with Spring. In general, you will have to follow the steps given below (if using Atomikos):
Retain your existing XA data source (rtsDatasource in your case) or create one if not already using (for example, if someone has a non-XA data source, that data source must be converted to an XA data source first).
Wrap the XA data source in an AtomikosDataSourceBean.
Point your EntityManagerFactory at the new AtomikosDataSourceBean instance.
Declare an XA transaction manager and an XA user transaction.
Wrap the XA transaction manager in a Spring JtaTransactionManager.
Use the Spring JtaTransactionManager.
A short configuration snippet using H2 database, Hibernate 4, Spring 4 and Atomikos 4 is shown below.
<bean class="org.h2.jdbcx.JdbcDataSource" id="originalDataStore" lazy-init="true">...</bean>
<bean class="com.atomikos.jdbc.AtomikosDataSourceBean" id="dataSource" init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="xaDS"/>
<property name="xaDataSource" ref="originalDataStore"/>
<property name="poolSize" value="3"/>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="dataSource" ref="dataSource"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.jta.platform">com.atomikos.icatch.jta.hibernate4.AtomikosPlatform</prop>
...
</props>
</property>
</bean>
<bean class="org.springframework.transaction.jta.JtaTransactionManager" id="transactionManager">
<property name="transactionManager">
<bean class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
<property name="forceShutdown" value="false"/>
</bean>
</property>
<property name="userTransaction">
<bean class="com.atomikos.icatch.jta.J2eeUserTransaction">
<property name="transactionTimeout" value="300"/>
</bean>
</property>
<property name="allowCustomIsolationLevels" value="true"/>
</bean>
<transaction:annotation-driven transaction-manager="transactionManager"/>
For details, you can see this app.

Using non-Spring Hibernate JPA DAO classes in a Spring application

I have a Maven project with a Hibernate JPA persistence layer that I would like to incorporate into some Spring applications (one a web application, and one a command line tool), but I am unsure how to configure this. The persistence module includes model classes, DAO classes, and the persistence.xml file. I have configured Spring's EntityManagerFactory to use the existing persistence.xml, but instantiating the DAO classes always results in a NullPointerException, as they seem to be unable to locate the persistence unit by name. Is it possible to use Hibernate JPA classes created outside Spring's context in a Spring application?
persistence.xml
<persistence-unit name="myapp" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.archive.autodetection" value="class, hbm" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
application-context.xml
<bean id="allProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:config/db.properties</value>
<value>classpath:config/log4j.properties</value>
</list>
</property>
</bean>
<context:component-scan base-package="com.company.app" />
<context:annotation-config />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="myapp"/>
<property name="dataSource" ref="datasource" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="databasePlatform" value="${hibernate.dialect}" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="datasource" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="${hibernate.connection.url}" />
<property name="username" value="${hibernate.connection.username}" />
<property name="password" value="${hibernate.connection.password}" />
</bean>
UserDao.java
public class UserDao extends AbstractDao<User> {
public UserDao() {
super("myapp");
}
// CRUD methods
AbstractDao.java
public abstract class AbstractDao<T extends DataObject> {
private EntityManagerFactory emf;
private final static Logger log = LoggerFactory.getLogger(AbstractDao.class);
private final Map<String, Map<String, String>> connectionDictionaries =
new HashMap<String, Map<String, String>>();
public AbstractDao(String dataSourceName) {
try {
setUpDataSource(dataSourceName);
} catch (IOException e) {
log.error("Unable to load: ", AbstractDataConstants.DB_PROPERTIES_FILE);
e.printStackTrace();
}
}
...
// Other methods

Persistance.xml vs DispatcherServlet

I am using JPA 2.0, Hibernate 3 Annotation Version, the problem is that i am confusing in Persistence.xml & DispatcherServlet
My persistence.xml file contains:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="Hello" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>models.student</class>
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/test"/>
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="admin" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
</properties>
</persistence-unit>
</persistence>
In my dispatcher servlet file I have following Beans:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="admin" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="Hello" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
Question is: why do we need to put all properties (DriverClassName, URL, UserName, Password) in both persistence.xml and in DataSource bean in DispatcherServlet?
I am learning and it is confusing me, please help.
Actually you have double configuration here.
You need either persistence.xml or bean definitions.
Take a look here

Unable to build EntityManagerFactory

persistence.xml file
<?xml version="1.0" encoding="UTF-8"?>
<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="xyz" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com......</class>
</persistence-unit>
</persistence>
ApplicationContext.xml
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:XE" />
<property name="username" value="yyy" />
<property name="password" value="yyy" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="xyz" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="showSql" value="true" />
<!-- <property name="generateDdl" value="true" /> -->
</bean>
</property>
</bean>
<bean id="theDao" class="com.cin.the.dataaccess.dao.the.TheJPA">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
the error i get is
[PersistenceUnit: xyz] Unable to build EntityManagerFactory
can any one tell me the mistake
The main problem was that the entites was not generated properly. so at the end of the stacktrace it was giving this error
Caused by: org.hibernate.MappingException: property mapping has wrong number of columns: com......date type: object
once the entity was generated correctly the problem was solved
Someone answered here:
If you define your persistence unit with the JTA transaction type, you
need also to define your datasource inside the jta-data-source
attribute.
Try adding this to your ApplicationContext.xml
<jee:jndi-lookup id="dataSource" jndi-name="your-jndi-name" />
and the following to <persistence-unit> element in persistence.xml:
<jta-data-source>your-jndi-name</jta-data-source>
You are getting this error because you have mapped your domain object datatype to be java.lang.Object. map it to more specific like a String, int, long...

Categories