2

小さな Spring-Hibernate-Mysql テスト プロジェクトに取り組んでいますが、何らかの理由でトランザクションが DB にコミットされません。

私のアプリケーションコンテキストでは、次のようになりました。

<!-- JTA -->

<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />

</bean>

<tx:annotation-driven transaction-manager="txManager" />

<!-- JPA -->

<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/myPU" />

<!-- In order to enable EntityManager injection -->
<bean
    class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">
    <property name="persistenceUnits">
        <map>
            <entry key="myPU" value="persistence/myPU" />
        </map>
    </property>
</bean>

私のpersistence.xml:

<persistence-unit name="myPU" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/mysqlResource</jta-data-source>
    <properties>
        <property name="hibernate.connection.shutdown" value="true" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"></property>
        <property name="hibernate.show_sql" value="true" />
    </properties>
</persistence-unit>

データベースに「persons」という単純なテーブルを作成しました。

CREATE TABLE persons(
id VARCHAR(255) PRIMARY KEY,
version int, 
full_name VARCHAR(255),
person_id VARCHAR(255),
email VARCHAR(255));

作成されたエンティティに対応するエンティティと Dao:

@Entity
@Table(name = "persons")
public class Person implements Serializable {

private static final long serialVersionUID = 4349832844316517922L;

/*--- Members ---*/

/**
 * Hibernate genetared UUID
 */
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
private String id;

@Version
private int version;

@Column(name = "full_name")
private String fullName;

@Column(name = "person_id")
private String personId;

@Column(name = "email")
private String eMail;

/*--- Constructor ---*/

public Person() {
}

/*--- Overridden Methods ---*/

@Override
public boolean equals(Object obj) {

    if ((obj == null) || !(obj instanceof Person)) {
        return false;
    }

    // reference comparison
    if (obj == this) {
        return true;
    }

    final Person other = (Person) obj;

    return new EqualsBuilder().append(getPersonId(), other.getPersonId())
            .append(geteMail(), other.geteMail())
            .append(getFullName(), other.getFullName()).isEquals();
}

/**
 * The unique hash code based on the clients' id and citizenship
 * 
 * {@inheritDoc}
 */
@Override
public int hashCode() {

    return new HashCodeBuilder().append(geteMail()).append(this.geteMail())
            .append(this.getFullName()).toHashCode();
}

/*--- Getters & Setters ---*/

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public int getVersion() {
    return version;
}

public void setVersion(int version) {
    this.version = version;
}

public String getFullName() {
    return fullName;
}

public void setFullName(String fullName) {
    this.fullName = fullName;
}

public String getPersonId() {
    return personId;
}

public void setPersonId(String personId) {
    this.personId = personId;
}

public String geteMail() {
    return eMail;
}

public void seteMail(String eMail) {
    this.eMail = eMail;
}

}

ダオ:

@Repository
public class PersonJpaDao extends BasicJpaDao<Person> implements IPersonDao {

public PersonJpaDao() {
    super(Person.class);
}

}

ここに BasicJpaDao があります:

public class BasicJpaDao<T> implements IBasicDao<T> {

/* --- Members --- */

/** The JPA utility to work with the persistence layer. */
@PersistenceContext
protected EntityManager entityManager;

/** The type of the entity to which this DAO offers access. */
protected Class<T> entityClass;

/* --- Constructors --- */

/**
 * Default constructor.
 * 
 * @param entityClass
 *            The type of the entity to which this DAO offers access.
 */
public BasicJpaDao(Class<T> entityClass) {
    super();
    this.entityClass = entityClass;
}

/* --- Public methods --- */

/**
 * {@inheritDoc}
 */
@Override
public void create(T entity) {
    getEntityManager().persist(entity);
}

/**
 * {@inheritDoc}
 */
@Override
public T read(Object primaryKey) {
    return getEntityManager().find(getEntityClass(), primaryKey);
}

/**
 * {@inheritDoc}
 */
@Override
public T update(T entity) {
    return getEntityManager().merge(entity);
}

/**
 * {@inheritDoc}
 */
@Override
public void delete(T entity) {
    getEntityManager().remove(entity);
}

/**
 * {@inheritDoc}
 */
@Override
public void flush() {
    getEntityManager().flush();
}

/* --- Getters/Setters --- */

/**
 * @return The JPA utility to work with the persistence layer.
 */
public EntityManager getEntityManager() {
    return this.entityManager;
}

/**
 * @param entityManager
 *            The JPA utility to work with the persistence layer.
 */
public void setEntityManager(EntityManager entityManager) {
    this.entityManager = entityManager;
}

/**
 * @return The type of the entity to which this DAO offers access.
 */
public Class<T> getEntityClass() {
    return entityClass;
}

/**
 * @param entityClass
 *            The type of the entity to which this DAO offers access.
 */
public void setEntityClass(Class<T> entityClass) {
    this.entityClass = entityClass;
}

Soo ..基本的には機能しますが、何もコミットされません。つまり、実行すると

@Transactional(propagation = Propagation.REQUIRED)
private void crearePerson() {
    Person p1 = myDao.read("12345");
    p1.setFullName("kiko too");
    myDao.update(p1);
}

(デバッグで) p1 が DB から戻ってくることがわかりますが、更新は行われません。私が見つけた唯一の近いものはこれでした:

JPA - トランザクションがコミットされていない

そして追加してみました

<property name="hibernate.connection.shutdown" value="true" />

このスレッドに続いて私のpersistence.xmlにアクセスしましたが、役に立ちませんでした。また、値が true の connection.shutdown というプロパティを (アプリケーション サーバー GUI の) 接続プールに追加しましたが、どちらも役に立ちませんでした。

更新: 私は JTA を使用しているので、トランザクション マネージャーの構成が間違っていると考えました。org.springframework.orm.jpa.JpaTransactionManager を使用していましたが、org.springframework.transaction.jta.JtaTransactionManager を使用する必要がありました。したがって、アプリケーションのコンテキストを変更したところ、次のようになりました。

<bean id="txManager"
    class="org.springframework.transaction.jta.JtaTransactionManager" />

<tx:annotation-driven transaction-manager="txManager" />

残念ながら、私はまだ同じ問題を経験しています:(私のコンソールでは、次のように休止状態のクエリを見ることができます()元のエンティティフィールドの一部を変更しましたが、実際には問題ではありません):

情報: 休止状態: user0_.id を id0_0_ として、user0_.email を email0_0_ として、user0_.full_name を full3_0_0_ として、user0_.password を password0_0_ として、user0_.update_by_email を update5_0_0_ として、user0_.user_name を user6_0_0_ として、user0_.version を version0_0_ として、ユーザー user0_ から選択します。 user0_.id=?

何か案は?

前もってありがとう、ヨギ

4

3 に答える 3

3

おそらく機能していない理由は@Transactional、プライベート メソッドを使用しているためです。@Transactionalプロキシ ジェネレーターはそれらを無視するため、非パブリック メソッドには影響しません。春のドキュメントから:

メソッドの可視性と @Transactional

プロキシを使用する場合は、@Transactional アノテーションを public な可視性を持つメソッドにのみ適用する必要があります。@Transactional アノテーションを使用して、保護されたプライベート メソッドまたはパッケージ可視メソッドにアノテーションを付けた場合、エラーは発生しませんが、アノテーションが付けられたメソッドは、構成されたトランザクション設定を示しません。非公開メソッドに注釈を付ける必要がある場合は、AspectJ (以下を参照) の使用を検討してください。

于 2012-05-23T00:51:19.203 に答える
0

create() メソッドに「@Transactional」を追加します。

編集:@Transactionalをdaoレイヤーではなくサービスレイヤーに配置することをお勧めします

于 2012-05-22T18:43:28.020 に答える