元の質問についてもう少し考えた後、追加したいと思います。
Spring は、すべてのメソッドを Transaction で自動的にラップするわけではありません。トランザクション境界を配置する場所を Spring に伝える必要があります。これは、XML 構成または @Transactional アノテーションを使用して行います。
トランザクションを宣言する必要がある場所を確認する必要があります - hereおよびhere。
Spring のトランザクション管理 (こちら) をご覧ください。
Transaction Config を参照してください。
あなたの構成は良好であり、あなたが抱えている問題は EntityManager を使用しようとしている Bean にあると私はまだ考えています。私はあなたがそれを見ることができれば、私はあなたを動かすことができると確信しているので、あなたにそれを投稿してほしいという私の要求を更新します.
設定を確認しましたが、問題は見つかりませんでした。例として、現在動作中のアプリケーションにあるものを (一番下に) 提供します。
問題は構成内にあるとは思いませんが、構成された Bean の使用に問題があります。EntityManager とどのようにやり取りしているかを示すコードを提供していただければ、問題を特定できる可能性があります。
エンティティ、リポジトリ、および XML 構成の実例を提供して、問題の特定に役立てます。
Spring 構成(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>
モデル
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);
}
}
リポジトリ
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);
}
}