Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧靴&x2B;冬眠+;JPA没有可用的事务实体管理器_Java_Spring_Hibernate_Jpa_Spring Boot - Fatal编程技术网

Java 弹簧靴&x2B;冬眠+;JPA没有可用的事务实体管理器

Java 弹簧靴&x2B;冬眠+;JPA没有可用的事务实体管理器,java,spring,hibernate,jpa,spring-boot,Java,Spring,Hibernate,Jpa,Spring Boot,我使用的是spring boot 1.2.3.0发行版,带有JPA over hibernate。我遇到以下异常 org.springframework.dao.InvalidDataAccessApiUsageException: No transactional EntityManager available; nested exception is javax.persistence.TransactionRequiredException: No transactional Entity

我使用的是spring boot 1.2.3.0发行版,带有JPA over hibernate。我遇到以下异常

org.springframework.dao.InvalidDataAccessApiUsageException: No transactional EntityManager available; nested exception is javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:410) ~[EntityManagerFactoryUtils.class:4.1.6.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223) ~[HibernateJpaDialect.class:4.1.6.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417) ~[AbstractEntityManagerFactoryBean.class:4.1.6.RELEASE]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) ~[ChainedPersistenceExceptionTranslator.class:4.1.6.RELEASE]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) ~[DataAccessUtils.class:4.1.6.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) ~[PersistenceExceptionTranslationInterceptor.class:4.1.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [ReflectiveMethodInvocation.class:4.1.6.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122) ~[CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.class:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [ReflectiveMethodInvocation.class:4.1.6.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [ExposeInvocationInterceptor.class:4.1.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [ReflectiveMethodInvocation.class:4.1.6.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) [JdkDynamicAopProxy.class:4.1.6.RELEASE]
at com.sun.proxy.$Proxy110.deleteByCustomerId(Unknown Source) ~[na:na]

Caused by: javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:275) ~[SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.class:4.1.6.RELEASE]
at com.sun.proxy.$Proxy102.remove(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.query.JpaQueryExecution$DeleteExecution.doExecute(JpaQueryExecution.java:270) ~[JpaQueryExecution$DeleteExecution.class:na]
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:74) ~[JpaQueryExecution.class:na]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:97) ~[AbstractJpaQuery.class:na]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:88) ~[AbstractJpaQuery.class:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:395) ~[RepositoryFactorySupport$QueryExecutorMethodInterceptor.class:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:373) ~[RepositoryFactorySupport$QueryExecutorMethodInterceptor.class:na]
以下是我的程序结构
配置类

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableTransactionManagement
public class WSApplication {
    public static void main(final String[] args) {
        SpringApplication.run(WSApplication.class, args);
    }
}

@Entity
@Table(Orders)
public class Order {
    @id
    @GeneratedValue
    private long id;

    @Column(name = "customerId")
    private Long customerId;

    // getter & setter methods
    // equals & hashCode methods
}

public interface OrderRepository extends JpaRepository<Order, Long> {

    List<Order> findByCustomerId(Long customerId);

    // 4- @Transactional works fine
    void deleteByCustomerId(Long cusotmerId);

}

public class OrderService {

    @Autowired
    private OrderRepository repo;

    // 3- @Transactional works fine
    public void deleteOrder(long customerId){
        //1- throws exception
        repo.deleteByCustomerId(customerId); 

        //2- following works fine
        //repo.delete(repo.findByCustomerId(customerId).get(0));
    }

}
@配置
@组件扫描
@启用自动配置
@启用事务管理
公共类WSP应用程序{
公共静态void main(最终字符串[]args){
run(WSApplication.class,args);
}
}
@实体
@表(订单)
公共阶级秩序{
@身份证
@生成值
私人长id;
@列(name=“customerId”)
私人长客户ID;
//getter和setter方法
//equals和hashCode方法
}
公共接口OrderRepository扩展了JpaRepository{
列出findByCustomerId(长customerId);
//4-@事务处理工作正常
无效deleteByCustomerId(长客户机);
}
公共类订购服务{
@自动连线
私人回购;
//3-@事务处理工作正常
公共无效删除订单(长客户ID){
//1-引发异常
回购删除客户ID(客户ID);
//2-以下工程罚款
//repo.delete(repo.findByCustomerId(customerId.get)(0));
}
}
在上面的服务类代码中,有谁能告诉我为什么2个有效,1个抛出异常


谢谢

好的,我找到了一种让它工作的方法

只需将
@Transactional
注释(org.springframework.transaction.annotation.Transactional)放在deleteOrder方法的OrderService中即可

@Transactional
public void deleteOrder(long customerId){
    repo.deleteByCustomerId(customerId);
}
我真的不知道为什么第二个有效。我猜,由于它是来自crudepository接口的直接方法,因此它知道如何以原子方式执行它

前者是对deleteByCustomerId的调用。将处理此调用以查找具有指定id的客户,然后将其删除。出于某种原因,它使用显式事务

这只是一个猜测。我将尝试联系一些spring开发人员,并可能打开一个问题来验证这种行为

希望有帮助


参考资料:

首先,我引用了,以证明
删除
方法在您的案例中起作用的原因(我指的是选项2

默认情况下,存储库实例上的CRUD方法是事务性的。对于 读取操作设置事务配置
readOnly
标志 为true,所有其他配置都使用普通的
@Transactional
,以便 默认事务配置适用。有关详细信息,请参阅的JavaDoc 积垢的

delete
方法实际上是
crudepository
的一种方法。您的存储库扩展了
JpaRepository
,它扩展了
CrudRespository
,因此它属于crudepository接口,根据上面的引用,它是事务性的

如果阅读本节,您将看到与选项4相同的内容,并且您将知道如何为存储库的所有方法应用自定义事务行为。 此外,文档的示例61显示了与选项3相同的场景

@Transactional
public void deleteOrder(long customerId){
    repo.deleteByCustomerId(customerId);
}
现在请记住,您不是在使用JDBC逻辑,在这种情况下,数据库负责事务,而是在基于ORM的框架内。ORM框架需要一个事务来触发对象缓存和数据库之间的同步。 因此,您必须了解并为执行ORM逻辑的方法(如
deleteByCustomerId
)提供事务上下文


默认情况下,
@Transactional
(我的意思是没有任何参数)将传播模式设置为
REQUIRED
,将readOnly标志设置为false。当您调用在中注释的方法时,如果不存在任何事务,则事务将被初始化。这就是@LucasSaldanha的解决方案(与使用facade为多个存储库调用定义事务的示例相同)和选项4起作用的原因。另一方面,如果没有事务,您将陷入选项1

的抛出异常中,即使在使用
@transactional
注释了我的
search()
方法之后,我仍然得到了
无可用的事务性EntityManager
异常

@Transactional
public void deleteOrder(long customerId){
    repo.deleteByCustomerId(customerId);
}
我接着介绍了如何在Spring Boot中设置Hibernate搜索

对我来说,问题是我对
hibernate搜索orm
有不同的依赖性。对我来说没有任何问题的依赖是

compile("org.hibernate:hibernate-search-orm:5.7.0.Final")
将其添加到gradle构建文件后,一切都按预期进行


希望这对其他人也有帮助。

谢谢,但我更想知道为什么deleteByCustomerId不起作用。根据我的理解,spring应该自动启动事务,就像它对delete方法所做的那样。为什么会这样呢,只有超级方法是事务性的,如果您希望自己的方法是事务性的,就必须将其标记为事务性的。其次,答案实际上是正确的(IMHO),因为您的事务边界应该是服务调用,而不是dao调用。文档应该更详细地提到这一点。谢谢你的帮助我想你指的是例81而不是例61。这一个对我有效,我使用的是5.11.0.Final,通过降级到5.7.0.Final,我成功了