Spring 4 hibernate 4 #Transactional(read-only="true") does not work - java

I use hibernate 4, spring 4, and I want to use #Transaction annotation, but it doesn't work.
The user object still saved on sqlServer.
Any idea what I'm doing wrong?
[applicationContext.xml]
<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan base-package="SpringDAO"/>
<context:component-scan base-package="SpringTest"/>
<context:component-scan base-package="service"/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation">
<value>hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.microsoft.sqlserver.jdbc.SQLServerDriver</value>
</property>
<property name="url">
<value>jdbc:sqlserver://127.0.0.1:1433;databaseName=test</value>
</property>
<property name="username">
<value>XXX</value>
</property>
<property name="password">
<value>XXX</value>
</property>
</bean>
[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>
<mapping class="SpringDAO.User" />
</session-factory>
</hibernate-configuration>
package SpringDAO;
#Repository("UserDAO3")
public class UserDAO3 {
SessionFactory sessionFactory;
#Autowired
public void setSessionFactory(SessionFactory value){
this.sessionFactory = value;
}
public SessionFactory getSessionFactory(){
return this.sessionFactory;
}
#Transactional(readOnly = true)
public boolean insert(Object user){
Session sess = this.sessionFactory.getCurrentSession();
sess.save(user);
return true;
}
}
package service;
#Service("UserService")
public class UserService {
public boolean addAction(User user){
boolean result = true;
UserDAO3 dao = (UserDAO3)SpringUtil.getBean("UserDAO3");
List<User> users = dao.searchAllUser();
for(User selectedUser : users){
if(selectedUser.getName().equals(user.getName())){
result = false;
break;
}
}
result = dao.insert(user);
return result;
}
}

From the docs,
This just
serves as a hint for the actual transaction subsystem; it will not
necessarily cause failure of write access attempts. A transaction
manager which cannot interpret the read-only hint will not throw an
exception when asked for a read-only transaction.
Whether the isolation level of the transaction can change depends on the implementation. Depending on the driver different things might occur, no guarantees, it does not enforce the failure.

POJO:
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Integer id;
Modification:
#Id
#Column(name = "id")
private Integer id;
It works after eliminating #GeneratedValue(strategy = GenerationType.AUTO)

have a look at #Transactional read-only flag pitfalls on ibm.com, the explanation there is really great. Your question is answered there.

Related

#Entitty and #EntityScan not work. I am using spring boot and jpa repository, something occurred many times

I am using spring boot and jpa repository, but #Entity and #EntityScan didn't work. The logs and main code graph are here
#SpringBootApplication
#EntityScan(basePackages = {"com.demo.detail"})
#EnableJpaRepositories(basePackages = {"com.demo.detail"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
the entity define here
#Entity
#EqualsAndHashCode(callSuper = true)
#DynamicUpdate
#Data
public class BizDO extends BaseDO {
#Id
private Long id;
private String bizKey;
private String links;
private String description;
private Integer status;
private String creator;
}
the repository define here
public interface BizRepository extends JpaRepository<BizDO, Long> {
}
I have wrote class BizDO and jpa-related configuration here
# application.properties
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
and the bean.xml here
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="org.wahid.cse.entity"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
</property>
</bean>

Caused by: org.hibernate.MappingException: Unable to load class declared as <mapping class="xxxxx"/> in the configuration:

In my spring web application I am getting this error on launching my spring application
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in ServletContext resource [/WEB-INF/spring/data.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/spring/data.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Unable to load class declared as <mapping class="reshetyk.alexey.diary.domain.DiaryUser"/> in the configuration:
Also I have this as a second error
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/spring/data.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Unable to load class declared as <mapping class="reshetyk.alexey.diary.domain.DiaryUser"/> in the configuration:
The class DiaryUser is defined in the package and have the following properties assuming the getters and setters are well defined
this is the complete code of my entity class for DiaryUser class.java
#Entity
#Table(name = "USERS")
public class DiaryUser implements Serializable {
#Id
#Column(name = "ID_USER")
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column(name = "LOGIN", unique = true, nullable = false)
private String login;
#Column(name = "PASSWORD", nullable = false)
private String password;
public DiaryUser() {
}
public DiaryUser(Integer id) {
this.id = id;
}
public DiaryUser(String login) {
this.login = login;
}
public DiaryUser(Integer id, String login, String password) {
this.id = id;
this.login = login;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
I have equally defined this in my hibernate.cfg.xml file
<hibernate-configuration>
<session-factory>
<mapping class="reshetyk.alexey.diary.domain.DiaryUser" />
<mapping class="reshetyk.alexey.diary.domain.DiaryCategory" />
<mapping class="reshetyk.alexey.diary.domain.DiaryRecord" />
</session-factory>
</hibernate-configuration>
this is my data.xml file that contains my database definition configuration for hibernate mappings
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
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"/>
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
I am kind of confused as I dont know why I am getting this error?
Instead of using LocalSessionFactoryBean,try using the AnnotationSessionFactoryBean instead and specify the mapping classes as shown below(check the link:AnnotationSessionFactoryBean)
<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
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="test.package"/>
</bean>
instead of defining the mappings under hibernate.cfg.xml.
Your sessionFactory details in data.xml file can be modified as below:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--<property name="configLocation" value="classpath:hibernate.cfg.xml"/>-->
<property name="annotatedClasses">
<list>
<value>reshetyk.alexey.diary.domain.DiaryUser</value>
<value>reshetyk.alexey.diary.domain.DiaryCategory</value>
<value>reshetyk.alexey.diary.domain.DiaryRecord</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
Please make sure that mapping resource is correctly defined.

Why Hibernate in showing two different Queries in the console for single Query?`

I am new to this Hibernate framework and using Hibernate 3 just to start using this framework.
I have a small module that is executing a update query.
public void saveProduct(Product prod) {
String hql = "UPDATE Product set description = :description, price = :price,ctr=ctr+1 WHERE id = :id";
Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
query.setParameter("description", prod.getDescription());
query.setParameter("price", prod.getPrice());
query.setParameter("id", prod.getId());
logger.info(prod.toString());
int result = query.executeUpdate();
logger.info("Rows affected: " + result);
}
These are logs for this particular module and i have issue in this part hibernate is showing two different update queries one without column ctr and other one with column ctr or is it a normal behaviour:
May 23, 2016 5:55:37 PM com.mogae.dashboard.db.dao.ProductDaoImp saveProduct
INFO: Description: test311;Price: 1.7279999999999998
Hibernate:
update
products
set
description=?,
price=?
where
id=?
Hibernate:
update
products
set
description=?,
price=?,
ctr=ctr+1
where
id=?
May 23, 2016 5:55:37 PM com.mogae.dashboard.db.dao.ProductDaoImp saveProduct
INFO: Rows affected: 1
This is my xml configuration for DB connectivity:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- the parent application context definition for the springapp application -->
<aop:config>
<aop:advisor pointcut="execution(* *..ProductManager.*(..))" advice-ref="txAdvice"/>
</aop:config>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<bean id="productDao" class="com.mogae.dashboard.db.dao.ProductDaoImp">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<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>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.password}"/>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
</list>
</property>
</bean>
</beans>
and this is my hibernate mapping file :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.mogae.dashboard.actions.domain.Product" table="products" lazy="false">
<id name="id" column="id" type="int">
<generator class="native">
<param name="sequence">products_id_seq</param>
</generator>
</id>
<property name="description" column="description" type="string" />
<property name="price" column="price" type="double" />
</class>
</hibernate-mapping>
and this is my entity (Product) class:
package com.mogae.dashboard.actions.domain;
import java.io.Serializable;
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("Description: " + description + ";");
buffer.append("Price: " + price);
return buffer.toString();
}
private String description;
private Double price;
private int id;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Please help i have been searching for this issue on the google and various hibernate forums but haven't found one.

Spring-JPA "Class is not entity"

I have an issue with my project using Spring (4.2.4 Release) and JPA (2.1)
To be brief the problem is in the part of code in file "Book.java":
#Table(name = "book")
#NamedQueries({
#NamedQuery(name = "Book.getBooks", query="select b from com.jpaProSpring.Book b ")
})
#Entity(name = "Book")
public class Book implements Serializable {
private int id;
private String title;
private String description;
public Book() {
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id")
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
#Column
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
#Column
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
}
and particulary in
query = "select b from com.jpaProSpring.Book b" )
My IntelliJ highlights the Book and says that class is not en entity. And I have no idea, why it is so given that I was doing an example from the book.
Link to my project https://github.com/yuraguz/LearnORM.git
My spring-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3310/testdb"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
<property name="initialSize" value="5"/>
<property name="maxActive" value="10"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="packagesToScan" value="com.jpaProSpring" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<context:annotation-config />
<context:component-scan base-package="com.jpaProSpring" />
</beans>
P.S: I know entities must be declared in persistence.xml in META-INF/ source. But if I understand correctly Spring4 make it possible to config project without persistance.xml. So, I don't use it.
If you use InellyJ Idea, possible you didn't add JPA facet in your project. Try open menu "File"->"Project Structure", then select in list of Project Settings section named "Facets". Check if you have configured JPA facet in list of facets. If you don't see JPA facet, just add it (by pressing "+" button). Optionally, you can specify persistence.xml (if you have it) and Default JPA provider. Hope this will help.

How to obtain an entitymanager in Spring 3 like you do in Java EE 6

I have used Java EE 6 before and I have created a connection resource (pooled) on the server and then bound it to a JNDI name which I have referenced inside the jta-data-source element tag in the Persistence.xml file.
Now I use Spring 3 and I have a hard time understanding all the different beans that I need to set up and why need to do so. EJB 3 automatically wrap the methods in transactions. In Spring it seems like you need to configure a transaction manager, however I don't know. Need explanation.
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/myapp" expected-type="javax.sql.DataSource"/>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="packagesToScan" value="com.myapp.app"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.PostgreSQL82Dialect
</prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
I understand the jndi lookup for the data source, however I don't understand the rest thourougly. I am not able to insert/persist objects with this configuration.
I need an explanation on how Spring 3 differs from Java EE 6 in this area, and how to do it the same way.
After thinking a little more on your original question, I'd like to add:
Spring doesn't automatically wrap every method with a Transaction. You have to tell Spring where you want your Transactional Boundaries to be. You do that with either XML config or by using the #Transactional annotation.
You should have a look at where you should declare transactions - here and here.
You should have a look at Spring's Transaction Management - here.
You should have a look at Transaction Config - here.
I am still of the opinion that your config is good and that the trouble you are having lies within the beans attempting to use your EntityManager. I renew my request for you to post that, as I'm certain I could get you going if I could see it.
I've looked at your configuration and I can't find anything wrong with it. As an example, I will provide (at the bottom) something I have in a working application right now.
I don't believe your problem is within your configuration, but in your usage of the configured beans. If you could provide code showing me (us) how you are interacting with your EntityManager, I could probably identify your issue(s).
I'll provide you with working examples of a Entity, Repository, and XML Config to try and help you locate your issue:
Spring Config (applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:annotation-config />
<context:component-scan base-package="com.company.app.dao" />
<context:component-scan base-package="com.company.app.service" />
<jee:jndi-lookup id="dataSource"
jndi-name="jdbc/Test" />
<bean id="jpaDialect"
class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<bean id="jpaAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
<bean id="entityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="jpaDialect" ref="jpaDialect" />
<property name="packagesToScan" value="com.company.app.model" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManager" />
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true" />
</beans>
Model
import org.hibernate.validator.constraints.Length;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
#Entity
public class User {
#Id
private String id = UUID.randomUUID().toString();
#Column
#Length(min = 3, max = 25)
private String name;
#OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true)
#JoinColumn(name = "userId", nullable = false)
private Set<Contact> contacts = new HashSet<Contact>();
public UUID getId() {
return UUID.fromString(id);
}
public void setId(UUID id) {
this.id = id.toString();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Contact> getContacts() {
return contacts;
}
public void setContacts(Set<Contact> contacts) {
this.contacts = contacts;
}
public void addContact(Contact contact) {
this.contacts.add(contact);
}
public void removeContact(Contact contact) {
this.contacts.remove(contact);
}
}
Repository
import com.company.app.model.User;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaQuery;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
#Repository
public class UserDao {
#PersistenceContext
private EntityManager em;
#Transactional(propagation = Propagation.REQUIRED)
public void createUser(User user) {
em.persist(user);
}
#Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public User readUserById(UUID id) {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
query.where (em.getCriteriaBuilder().equal(query.from(User.class).get("id"),id.toString()));
return em.createQuery(query).getSingleResult();
}
#Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public Set<User> readAll() {
CriteriaQuery<User> query = em.getCriteriaBuilder().createQuery(User.class);
query.from(User.class);
return new HashSet<User>(em.createQuery(query).getResultList());
}
#Transactional(propagation = Propagation.REQUIRED)
public User update(User user) {
return em.merge(user);
}
#Transactional(propagation = Propagation.REQUIRED)
public void delete(User user) {
em.remove(user);
}
}

Categories