我对@Transactional annotation和EntityManager persist和merge方法有奇怪的行为。我将method注释为@transactional,并在其中调用EntityManager.persists(entity)...但什么也没有发生。实体没有保存到数据库,没有激发异常,完全没有。我已经读了大量的例子,所以问题,我的代码看起来很好,但不工作。
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jndi.JndiTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {"com.mycompany"})
@DependsOn({"PropertiesConfig"})
public class HibernateConfig {
public HibernateConfig() {}
@Bean
public DataSource dataSource() throws NamingException {
return (DataSource) new JndiTemplate().lookup(PropertyService.getInstance().getProperty("jndi.jdbc.AGSQL"));
}
@Bean(name = "entityManager")
@DependsOn("dataSource")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
System.out.println("*** Init EntityManagerFactory ***");
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPersistenceProviderClass(HibernatePersistenceProvider.class);
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.mycompany" });
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setJpaProperties(hibernateProperties());
return em;
}
@Bean(name = "tm")
public PlatformTransactionManager transactionManager() throws NamingException {
System.out.println("*** Init TransactionManager ***");
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private Properties hibernateProperties() {
return new Properties() {
{
setProperty("hibernate.dialect", PropertyService.getInstance().getProperty("hibernate.dialect"));
setProperty("show_sql", PropertyService.getInstance().getProperty("show_sql"));
setProperty("hibernate.connection.isolation", String.valueOf(Connection.TRANSACTION_READ_UNCOMMITTED));
}
};
}
}
实体:
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "Vehicle", schema = "dbo")
public class VehicleEntity {
private Long deviceId;
private LocalDateTime dtEdit;
private String name;
@Id
@Column(name = "device_id")
public Long getDeviceId() {
return deviceId;
}
public void setDeviceId(Long deviceId) {
this.deviceId = deviceId;
}
@Basic
@Column(name = "dt_edit")
@UpdateTimestamp
public LocalDateTime getDtEdit() {
return dtEdit;
}
public void setDtEdit(LocalDateTime dtEdit) {
this.dtEdit = dtEdit;
}
@Basic
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
道:
import com.mycompany.VehicleEntity;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Repository
public class VehicleDao {
@PersistenceContext(unitName = "entityManager")
private EntityManager entityManager;
protected EntityManager getEntityManager() {
return entityManager;
}
@Transactional(transactionManager = "tm")
public void persist(VehicleEntity entity) {
getEntityManager().persist(entity);
}
@Transactional("tm")
public void merge(VehicleEntity entity) {
getEntityManager().merge(entity);
}
}
执行这段代码完全不做任何事情:
VehicleEntity ve = new VehicleEntity();
ve.setDeviceId(111L);
ve.setName("111");
vehicleDao.persist(ve);
((Session)this.getEntityManager().getDelegate()).getTransaction().getStatus() = NOT_ACTIVE
@Transactional(transactionManager = "tm")
public void persist(T entity) {
getEntityManager().joinTransaction();
getEntityManager().persist(entity);
}
@Transactional(transactionManager = "tm", propagation = Propagation.MANDATORY)
public void persist(T entity) {
getEntityManager().persist(entity);
}
它会抛出一个异常:
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
编辑2:
Spring version 5.1.7.RELEASE
Hibernate version 5.4.10.Final
javax.persistence:javax.persistence-api:2.2 (dependency from hibernate-core)
最后发现了问题:我从SessionFactory迁移到EntityManager,并在配置文件中保留了SessionFactory的旧设置。问题是事务管理器对SF和EM有相同的方法名称:
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(SessionFactory sessionFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(sessionFactory);
return transactionManager;
}
@Bean(name = "tm")
public PlatformTransactionManager transactionManager(@Qualifier("customEntityManager") EntityManagerFactory emf) {
System.out.println("*** Init TransactionManager ***");
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
尽管bean的名称不同,但这是错误的。将SF事务管理器方法更改为sessionTransactionManager(...)解决问题。
问题内容: 我对Spring 3.2.3 @Transactional注解有疑问。我的服务类如下所示: 如果我调用persist()方法,所有方法都可以正常工作。但是,如果我在类级别将@Transactional注释掉- 事务将不会启动。谁能告诉我为什么Spring只能在methol级忽略@Transactional? 问题答案: 您不能从processDisclosureData()调用pers
问题内容: 我在带有MySQL 5.0 DB的WebSphere Application Server 8上使用OpenJPA 2.2.0。 我有一个要合并到数据库中的对象列表。 就像是: 当我运行此循环时,我需要大约300-600毫秒来合并一个对象。当我删除“ em.merge(ob);”行时 那么我需要“ 0”毫秒来遍历1个列表对象。 所以我的问题是:我该怎么做才能缩短合并一个对象的时间? 谢
我正在@Async和@Transactional方法中的@Service类中执行一些持久化操作。 在这种方法中,我们持久化一些对象,然后在同一事务中持久化与这些已持久化对象相关的新对象。 JPA抛出一个异常,因为他认为这个相关对象没有被持久化: 这是我的服务类结构: 我想是与事务和异步方法有关,因为相同的代码在没有Async注释时工作。 我还尝试在Transactional注释中使用传播,但不起作
摘自Java Persistence with Hibernate(Manning,2007)第419页: 我应该在会话上使用持久化()吗?Hibernate会话接口还具有一个持久化()方法。它与JPA的持久化()操作具有相同的语义学。但是,这两种操作在刷新方面有一个重要的区别。在同步期间,Hibernate会话不会将持久化()操作级联到关联的实体和集合,即使您使用此选项映射了关联。它只级联到调用
问题内容: 到目前为止,我的偏好是始终使用EntityManager 来处理插入和更新。但是我还注意到,合并会在更新/插入之前执行其他选择查询,以确保数据库中不存在记录。 现在,我正在一个需要对数据库进行大量(批量)插入的项目。从性能的角度来看,在我绝对知道我一直在创建要持久化的对象的新实例的情况下,使用持久化而不是合并有意义吗? 问题答案: 它不是用一个好主意时,就足够了- 做了很多更多的工作。
我正在阅读JPA 2.1规范,有这个片段: 通过调用新实体实例上的persist方法或级联persist操作,新实体实例将同时成为托管实例和持久实例。应用于实体X的持久化操作的语义如下:。。。 是否可以在不显式调用persist()方法的情况下调用persist操作,或者persist操作始终必须是通过调用persist()的触发器? 假设我有两个实体A和B,其中A与B有一个域(cascade=P