0

以前に Java EE 6 を使用したことがあり、サーバー上に (プールされた) 接続リソースを作成し、それをjta-data-sourcePersistence.xml ファイルの要素タグ内で参照した JNDI 名にバインドしました。

現在、Spring 3 を使用していますが、セットアップする必要があるさまざまな Bean と、その必要がある理由をすべて理解するのに苦労しています。EJB 3 は、メソッドをトランザクションで自動的にラップします。Spring では、トランザクション マネージャーを構成する必要があるようですが、わかりません。説明が必要です。

<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" />

データ ソースの jndi ルックアップは理解できますが、残りは完全には理解できません。この構成ではオブジェクトを挿入/保持できません。

この分野で Spring 3 が Java EE 6 とどのように異なるか、および同じ方法でそれを行う方法について説明が必要です。

4

1 に答える 1

2

元の質問についてもう少し考えた後、追加したいと思います。

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);
    }
}
于 2013-04-19T15:40:48.617 に答える