I have Spring MVC application divided on layers. One of them is Service and here's one of the methods
#Transactional
public boolean deleteProject(long id){
Project project = projectDAO.read(id);
taskDAO.deleteAllByProject(project);
projectDAO.delete(project);
return true;
}
It deletes tasks, but project remains in the db (with no error or exception). I didnt use #Transactional in repository classes.
Here's my Spring config
<?xml version="1.0" encoding="UTF-8"?>
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/automate" />
<property name="username" value="postgres" />
<property name="password" value="" />
</bean>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="ru.jeak.keep" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="connection.pool_size">3</prop>
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
<prop key="hibernate.default_schema">test</prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id="userHibernateDAO" class="ru.jeak.keep.repository.hibernate.UserHibernateDAO" />
<bean id="projectHibernateDAO" class="ru.jeak.keep.repository.hibernate.ProjectHibernateDAO" />
<bean id="taskHibernateDAO" class="ru.jeak.keep.repository.hibernate.TaskHibernateDAO" />
UPDATE
I added persistence #Transactional to DAO class and it works now. But Im still confused why Spring did not do the rollback of deleting tasks after failure of deleting project
Related
I have a spring batch application that uses Azure SQL server as a backend, I am using Hibernate to update the database.
Below is my Hibernate configuration
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager" lazy-init="true">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2012Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
</props>
</property>
</bean>
<bean class="org.springframework.batch.core.scope.StepScope" />
<!-- DATA SOURCE -->
<bean id="demoDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="url" value="jdbc:sqlserver://demo.database.windows.net:1433;database=sqldb;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;" />
<property name="username" value="user1" />
<property name="password" value="p#ssword1" />
</bean>
I want know all the list of queries and its average execution time, how do I achieve this?
You can check p6spy. This tool wraps your datasource and logs all queries along with their execution time.
I'm working with Hibernate. How can I configure my applicationContext.xml to have an H2 in-memory databaseorg.hibernate.dialect.H2Dialect dont work
Spring configuration
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.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:tcp://localhost/~/test" />
<property name="username" value="sa" />
<property name="password " value="" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.emusicstore</value>
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
You are not connecting to an in-memory database. Your JDBC URL is for network connection to localhost:
jdbc:h2:tcp://localhost/~/test
To use the in-memory H2 the URL must look like this, containing mem:
jdbc:h2:mem:testdb
In the manual, see the section on In-Memory Database
Use embedded db datasource (with dbcp connection pool) instead of drivermanager datasource.
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:db/sql/create-db.sql" />
<jdbc:script location="classpath:db/sql/insert-data.sql" />
</jdbc:embedded-database>
<bean id="dbcpDataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:hsqldb:mem:dataSource" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource" ref="dbcpDataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.emusicstore</value>
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
I am miagrating my database from MySql to H2 and I keep getting the error message
org.h2.jdbc.JdbcSQLException: Table "DEVICE" not found
Everything was mapped correctly and worked with MySql. I only changed the context.xml file to work with H2 and added a dependency for H2 in the Pom.xml file.
context.xml file:
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:~/dataStore2"/>
<property name="username" value="" />
<property name="password" value="" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.entities" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="format_sql">true</prop>
<prop key="use_sql_comments">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
The Device class:
package com.entities;
#Entity
#Table(name="DEVICE")
public class Device {
...
}
You're missing
<prop key="hibernate.hbm2ddl.auto">create</prop>
in
<property name="hibernateProperties">
to force Hibernate to create schema based on entity classes if it is missing. You also need to change dialect from MySQL to H2:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.entities" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="format_sql">true</prop>
<prop key="use_sql_comments">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
Reference: Hibernate, Chapter 3. Configuration, Table 3.7. Miscellaneous Properties
I am using a configuration in my spring-hibernate application. The configuration is given below. My Question is, what the purposes & duties of, DataSource, sessionFactory, Transaction Manager and JPA Template here. And why one bean id is used in another one.
<!-- DataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan" value="net.softengine.edu.model"/>
</bean>
<!-- Transaction Manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- JPA Template -- >
<bean id="jpaTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
I remix Spring Data and Hibernate in my Application to access MS-SQL Data.
In My All Service class,I set #Transactional(readOnly=true) in front of the class name.Recently,I observe some DB Table Locks occurrence.
Otherwise,I set#Transactional(readOnly=true,isolation = Isolation.READ_UNCOMMITTED) to avoid DB Table lock,but it throws
org.springframework.transaction.InvalidIsolationLevelException: Standard JPA does not support custom isolation levels - use a special JpaDialect for your JPA implementation.
How can I modify the XML to use isolation = Isolation.READ_UNCOMMITTED for dirty read?
<!-- JPA Configurations -->
<!-- <jee:jndi-lookup id="myContactDataSource" jndi-name="jdbc/GNWEB" lookup-on-startup="false"
proxy-interface="javax.sql.DataSource"/> -->
<!-- use annotation in Service: #Transactional -->
<bean id="transactionManager2" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<qualifier value="transactionManager2"/>
</bean>
<bean id="oracleConnection" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/OracleDB</value>
</property>
</bean>
<bean id="oracleTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="oracleConnection" />
<qualifier value="oracleConnectionTransactionManager"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="mssqlDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="url">
<value>${connection.url}</value>
</property>
<property name="username">
<value>${connection.username}</value>
</property>
<property name="password">
<value>${connection.1qaz#WSX}</value>
</property>
</bean>
<bean id="auditInterceptor" class="com.bot.gnweb.unit.AuditIntercepter"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" destroy-method="destroy">
<property name="dataSource" ref="mssqlDataSource" />
<property name="entityInterceptor" ref="auditInterceptor"/>
<property name="packagesToScan">
<value>com.bot.gnweb.model</value>
</property>
<property name="mappingResources">
<list>
<value>gnwebSql.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.dialect">com.bot.gnweb.model.MssqlCustomDialect</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="net.sf.ehcache.configurationResourceName">ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="auditInterceptor">
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" />
<property name="persistenceUnitName" value="gnWebPU" />
<property name="dataSource" ref="mssqlDataSource" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
</bean>
<!-- Spring Data -->
<jpa:repositories base-package="com.bot.gnweb.repository"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager" />
<bean id="auditorBean" class="com.bot.gnweb.model.AuditingAware" />
<jpa:auditing auditor-aware-ref="auditorBean" />