小さな 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 から戻ってくることがわかりますが、更新は行われません。私が見つけた唯一の近いものはこれでした:
そして追加してみました
<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=?
何か案は?
前もってありがとう、ヨギ