使用Java Spring、Hibernate和EntityManager的@Transactional方法中的事务提交问题

使用Java Spring、Hibernate和EntityManager的@Transactional方法中的事务提交问题,java,spring,hibernate,transactions,entitymanager,Java,Spring,Hibernate,Transactions,Entitymanager,我试图学习Spring,Hibernate和H2数据库,使用ingeMaven构建代码。目前,我在如何正确使用@Transactional注释自动启动事务并在entityManager.persist成功或回滚时提交事务方面遇到了一些问题 我的测试项目非常简单。POJO类是Person,包含名字、姓氏和电子邮件地址。有一个服务类PersonSerice,它是一个接口,提供CRUD函数来添加、更改、读取和删除个人数据。有一个PersonServiceImpl调用DAO类的方法。这里是PersonD

我试图学习Spring,Hibernate和H2数据库,使用ingeMaven构建代码。目前,我在如何正确使用@Transactional注释自动启动事务并在entityManager.persist成功或回滚时提交事务方面遇到了一些问题

我的测试项目非常简单。POJO类是Person,包含名字、姓氏和电子邮件地址。有一个服务类PersonSerice,它是一个接口,提供CRUD函数来添加、更改、读取和删除个人数据。有一个PersonServiceImpl调用DAO类的方法。这里是PersonDAOImpl::createPerson方法的示例代码 使用

一切正常。有一个Hibernate SQL输出

“冬眠: 调用hibernate\u序列hibernate的下一个值: 插入 进入 人 (电子邮件、姓名、姓名、id) 价值观 (?,?,?,?)”

我不想手动调用entityManager.getTransaction().commit() 因此,我尝试在调用DAO方法的ServiceImpl方法中编写@Transactional

    public void createPerson(Person person) {
    entityManager.getTransaction().begin();
    entityManager.persist(person);
    entityManager.getTransaction().commit();
}
现在它不能正常工作。我刚得到一份工作。 “冬眠: 调用hibernate_序列的下一个值 " 数据库中写入了一些内容,但如果没有手动提交,我无法列出所有条目或删除它们。 因此,我目前不知道是什么问题,也不知道如何让@Transactional自动提交。 以下是Eclipse调试器中显示的entityManager内容的一部分:

entityManager$Proxy26(id=33) h ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler(id=116)
容器管理的false
异常Translator null jta错误 与事务同步错误
目标会话mpl(id=122)
actionQueue actionQueue(id=306)
... autoJoinTransactions true

我想我的主要问题可能在xml资源文件中,所以我想在这里展示它们。 这是我的Beans.xlm(./src/main/resources/Beans.xml)

这里是Person.java

package maven.springhibernateh2.basic;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;


@Entity
@Table(name="person")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    private int personId;

    @Column(name = "vorname")
    private String Vorname;

    @Column(name = "nachname")
    private String Nachname;

    @Column(name = "email")
    private String Emailadresse;
    public int getPersonId() {
        return personId;
    }
    public void setPersonId(int personId) {
        this.personId = personId;
    }
    public String getVorname() {
        return Vorname;
    }
    public void setVorname(String vorname) {
        Vorname = vorname;
    }
    public String getNachname() {
        return Nachname;
    }
    public void setNachname(String nachname) {
        Nachname = nachname;
    }
    public String getEmailadresse() {
        return Emailadresse;
    }
    public void setEmailadresse(String emailadresse) {
        Emailadresse = emailadresse;
    }

    public String toString() {
        return "Person [PersonId=" + personId + ", Vorname=" + Vorname + ", Nachname=" + Nachname + ", Emailadresse=" + Emailadresse + "]";
    }
}
PersonService.java

package maven.springhibernateh2.basic;

import java.util.List;

public interface PersonService {
    public abstract void addPerson(Person person);
    public abstract Person fetchPersonById(int personId);
    public abstract void deletePersonByID(int personId);
    public abstract void updatePersonEmailByID(String newEmail, int personId);
    public abstract List<Person> getAllPersonInfo();
}
包maven.springhibernateh2.basic;
导入java.util.List;
公共接口人员服务{
公开摘要无效人(人);
公共抽象人物fetchPersonById(int personId);
公共摘要void deletePersonByID(int personId);
公共摘要void updatePersonEmailByID(字符串newEmail,int personId);
公共摘要列表getAllPersonInfo();
}
PersonServiceImpl.java

package maven.springhibernateh2.basic;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component("personService")
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonDAO personDAO;

    public void setPersonDAO(PersonDAO personDAO) {
        this.personDAO = personDAO;
    }

    @Transactional
    public void addPerson(Person person) {
        personDAO.createPerson(person);
    }

    @Transactional
    public Person fetchPersonById(int personId) {
        return personDAO.getPersonById(personId);
    }

    @Transactional
    public void deletePersonByID(int personId) {
        personDAO.deletePersonByID(personId);
    }

    @Transactional
    public void updatePersonEmailByID(String newEmail, int personId) {
        personDAO.updatePersonEmailByID(newEmail, personId);
    }

    @Transactional
    public List<Person> getAllPersonInfo() {
        return personDAO.getAllPersonData();
    }
}
包maven.springhibernateh2.basic;
导入java.util.List;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.stereotype.Component;
导入org.springframework.transaction.annotation.Transactional;
@组件(“personService”)
公共类PersonServiceImpl实现PersonService{
@自动连线
私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人;
公共无效设置PersonDAO(PersonDAO PersonDAO){
this.personDAO=personDAO;
}
@交易的
公众人士(人){
personDAO.createPerson(person);
}
@交易的
公众人物fetchPersonById(int personId){
返回personDAO.getPersonById(personId);
}
@交易的
public void deletePersonByID(int personId){
personDAO.deletePersonByID(personId);
}
@交易的
public void updatePersonEmailByID(字符串newEmail,int personId){
personDAO.updatePersonEmailByID(newEmail,personId);
}
@交易的
公共列表getAllPersonInfo(){
返回personDAO.getAllPersonData();
}
}
PersonDAO.java

package maven.springhibernateh2.basic;

import java.util.List;

public interface PersonDAO {
    public abstract void createPerson(Person person);
    public abstract Person getPersonById(int personId);
    public abstract void deletePersonByID(int personId);
    public abstract void updatePersonEmailByID(String newEmail, int personId);
    public abstract List<Person> getAllPersonData();

}
包maven.springhibernateh2.basic;
导入java.util.List;
公共接口PersonDAO{
公开摘要无效人(人);
公共抽象人物getPersonById(int personId);
公共摘要void deletePersonByID(int personId);
公共摘要void updatePersonEmailByID(字符串newEmail,int personId);
公共摘要列表getAllPersonData();
}
PersonDAOImpl.java

package maven.springhibernateh2.basic;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;


@Repository
public class PersonDAOImpl implements PersonDAO {

    @PersistenceUnit(name = "roland.egger.maven.springhibernate")
    private EntityManagerFactory entityManagerFactory;    

    private EntityManager entityManager;

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public EntityManagerFactory getEntityManagerFactory() {
        return entityManagerFactory;
    }

    @PersistenceUnit
    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
        this.entityManager = this.entityManagerFactory.createEntityManager();
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }


    public void createPerson(Person person) {
        entityManager.persist(person);
    }

    public Person getPersonById(int personId) {
        Person person = entityManager.find(Person.class, personId);
        return person;
    }

    public void deletePersonByID(int personId) {
        Person person = getPersonById(personId);
        if (person != null) {
            //entityManager.getTransaction().begin();
            entityManager.remove(person);
            //entityManager.getTransaction().commit();
        }
    }

    public void updatePersonEmailByID(String newEmail, int personId) {
        Person person = getPersonById(personId);
        if (person != null)
        { 
            entityManager.getTransaction().begin();
            person.setEmailadresse(newEmail);
            entityManager.getTransaction().commit();
        }
    }

    public List<Person> getAllPersonData() {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Person> cq = cb.createQuery(Person.class);
        Root<Person> rootEntry = cq.from(Person.class);
        CriteriaQuery<Person> all = cq.select(rootEntry);
        TypedQuery<Person> allQuery = entityManager.createQuery(all);
        return allQuery.getResultList();
    }

}
包maven.springhibernateh2.basic;
导入java.util.List;
导入javax.persistence.EntityManager;
导入javax.persistence.EntityManagerFactory;
导入javax.persistence.PersistenceUnit;
导入javax.persistence.TypedQuery;
导入javax.persistence.criteria.CriteriaBuilder;
导入javax.persistence.criteria.CriteriaQuery;
导入javax.persistence.criteria.Root;
导入org.springframework.stereotype.Repository;
@存储库
公共类persondaimpl实现PersonDAO{
@PersistenceUnit(name=“roland.egger.maven.springhibernate”)
私人实体管理工厂实体管理工厂;
私人实体管理者实体管理者;
公共无效设置EntityManager(EntityManager EntityManager){
this.entityManager=entityManager;
}
公共EntityManagerFactory getEntityManagerFactory(){
返回实体管理工厂;
}
@持久性单位
公共无效设置EntityManagerFactory(EntityManagerFactory EntityManagerFactory){
this.entityManagerFactory=entityManagerFactory;
this.entityManager=this.entityManager工厂.createEntityManager();
}
公共实体管理器getEntityManager(){
返回实体管理器;
}
公众人士(人){
实体管理者坚持(人);
}
公众人物getPersonById(int personId){
Person-Person=entityManager.find(Person.class,personId);
返回人;
}
public void deletePersonByID(int personId){
Person-Person=getPersonById(personId);
if(person!=null){
//entityManager.getTransaction().begin();
实体经理(人);
//entityManager.getTransaction().commit();
}
}
公共空间更新
package maven.springhibernateh2.basic;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;


@Entity
@Table(name="person")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    private int personId;

    @Column(name = "vorname")
    private String Vorname;

    @Column(name = "nachname")
    private String Nachname;

    @Column(name = "email")
    private String Emailadresse;
    public int getPersonId() {
        return personId;
    }
    public void setPersonId(int personId) {
        this.personId = personId;
    }
    public String getVorname() {
        return Vorname;
    }
    public void setVorname(String vorname) {
        Vorname = vorname;
    }
    public String getNachname() {
        return Nachname;
    }
    public void setNachname(String nachname) {
        Nachname = nachname;
    }
    public String getEmailadresse() {
        return Emailadresse;
    }
    public void setEmailadresse(String emailadresse) {
        Emailadresse = emailadresse;
    }

    public String toString() {
        return "Person [PersonId=" + personId + ", Vorname=" + Vorname + ", Nachname=" + Nachname + ", Emailadresse=" + Emailadresse + "]";
    }
}
package maven.springhibernateh2.basic;

import java.util.List;

public interface PersonService {
    public abstract void addPerson(Person person);
    public abstract Person fetchPersonById(int personId);
    public abstract void deletePersonByID(int personId);
    public abstract void updatePersonEmailByID(String newEmail, int personId);
    public abstract List<Person> getAllPersonInfo();
}
package maven.springhibernateh2.basic;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component("personService")
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonDAO personDAO;

    public void setPersonDAO(PersonDAO personDAO) {
        this.personDAO = personDAO;
    }

    @Transactional
    public void addPerson(Person person) {
        personDAO.createPerson(person);
    }

    @Transactional
    public Person fetchPersonById(int personId) {
        return personDAO.getPersonById(personId);
    }

    @Transactional
    public void deletePersonByID(int personId) {
        personDAO.deletePersonByID(personId);
    }

    @Transactional
    public void updatePersonEmailByID(String newEmail, int personId) {
        personDAO.updatePersonEmailByID(newEmail, personId);
    }

    @Transactional
    public List<Person> getAllPersonInfo() {
        return personDAO.getAllPersonData();
    }
}
package maven.springhibernateh2.basic;

import java.util.List;

public interface PersonDAO {
    public abstract void createPerson(Person person);
    public abstract Person getPersonById(int personId);
    public abstract void deletePersonByID(int personId);
    public abstract void updatePersonEmailByID(String newEmail, int personId);
    public abstract List<Person> getAllPersonData();

}
package maven.springhibernateh2.basic;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;


@Repository
public class PersonDAOImpl implements PersonDAO {

    @PersistenceUnit(name = "roland.egger.maven.springhibernate")
    private EntityManagerFactory entityManagerFactory;    

    private EntityManager entityManager;

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public EntityManagerFactory getEntityManagerFactory() {
        return entityManagerFactory;
    }

    @PersistenceUnit
    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
        this.entityManager = this.entityManagerFactory.createEntityManager();
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }


    public void createPerson(Person person) {
        entityManager.persist(person);
    }

    public Person getPersonById(int personId) {
        Person person = entityManager.find(Person.class, personId);
        return person;
    }

    public void deletePersonByID(int personId) {
        Person person = getPersonById(personId);
        if (person != null) {
            //entityManager.getTransaction().begin();
            entityManager.remove(person);
            //entityManager.getTransaction().commit();
        }
    }

    public void updatePersonEmailByID(String newEmail, int personId) {
        Person person = getPersonById(personId);
        if (person != null)
        { 
            entityManager.getTransaction().begin();
            person.setEmailadresse(newEmail);
            entityManager.getTransaction().commit();
        }
    }

    public List<Person> getAllPersonData() {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Person> cq = cb.createQuery(Person.class);
        Root<Person> rootEntry = cq.from(Person.class);
        CriteriaQuery<Person> all = cq.select(rootEntry);
        TypedQuery<Person> allQuery = entityManager.createQuery(all);
        return allQuery.getResultList();
    }

}
@PersistenceContext
private EntityManager entityManager;
@Repository
public class PersonDAOImpl implements PersonDAO {

    private EntityManagerFactory entityManagerFactory;    

    @PersistenceContext
    private EntityManager entityManager;

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public EntityManagerFactory getEntityManagerFactory() {
        return entityManagerFactory;
    }

    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
        this.entityManager = this.entityManagerFactory.createEntityManager();
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }


    public void createPerson(Person person) {
        entityManager.persist(person);
    }
...
" javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call "
entityManager   $Proxy26  (id=40)   
h   SharedEntityManagerCreator$SharedEntityManagerInvocationHandler  (id=47)    
           logger   LogAdapter$Slf4jLocationAwareLog  (id=51)   
           properties   null
           proxyClassLoader Launcher$AppClassLoader  (id=55)
           synchronizedWithTransaction  true    
           targetFactory    $Proxy23  (id=62)
INFO  | 2020-05-09 22:44:44,953 |                                      |        | main | maven.springhibernateh2.basic.CRUDTest - Programmanfang... 
 INFO  | 2020-05-09 22:44:45,486 |                                      |        | main | org.hibernate.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: roland.egger.maven.springhibernate] 
 INFO  | 2020-05-09 22:44:45,532 |                                      |        | main | org.hibernate.Version - HHH000412: Hibernate ORM core version 5.4.15.Final 
 INFO  | 2020-05-09 22:44:45,657 |                                      |        | main | org.hibernate.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.1.0.Final} 
 INFO  | 2020-05-09 22:44:46,193 |                                      |        | main | org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect 
 Hibernate: 

    drop table if exists person CASCADE 
Hibernate: 

    drop sequence if exists hibernate_sequence
Hibernate: create sequence hibernate_sequence start with 1 increment by 1
Hibernate: 

    create table person (
       id integer not null,
        email varchar(255),
        nachname varchar(255),
        vorname varchar(255),
        primary key (id)
    )
INFO  | 2020-05-09 22:44:46,877 |                                      |        | main | org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 
 INFO  | 2020-05-09 22:44:46,884 |                                      |        | main | org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'roland.egger.maven.springhibernate' 
 ERROR | 2020-05-09 22:44:46,987 |                                      |        | main | maven.springhibernateh2.basic.CRUDTest - javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call 
 INFO  | 2020-05-09 22:44:46,987 |                                      |        | main | maven.springhibernateh2.basic.CRUDTest - Programmende... 
 INFO  | 2020-05-09 22:44:46,988 |                                      |        | main | org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'roland.egger.maven.springhibernate' 
       <!--  <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />  -->
       <tx:annotation-driven transaction-manager="transactionManager" /> 
...
       <aop:config proxy-target-class="true"/>