【问题标题】:Spring JpaRepository not working with transactionalSpring JpaRepository 不适用于事务性
【发布时间】:2021-05-12 21:42:06
【问题描述】:

我有如下界面:

public interface SnapshotRepository extends JpaRepository<Snapshot, Integer>, ISnapshotRepositoryExtra { }

如您所见,扩展:

public interface ISnapshotRepositoryExtra {
    Optional<Snapshot> latest();
}

...我在以下类中实现了 latest() 方法:

@Transactional
public class SnapshotRepositoryExtra implements ISnapshotRepositoryExtra {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Optional<Snapshot> latest() {
        return (Optional<Snapshot>) entityManager
                .createQuery("SELECT r FROM snapshot r order by timestamp DESC LIMIT 1")
                .getResultStream().findFirst();
    }
}

但是当我启动项目时,我看到:

java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.Optional com...persistance.snapshot.ISnapshotRepositoryExtra.latest()! No property latest found for type Snapshot!

所以我的问题是,为什么 Spring 看不到我刚刚创建的 SnapshotRepositoryExtra 类?

【问题讨论】:

  • 因为 Spring 尝试自己实现接口。为什么不使用@NativeQuery 的接口方法?
  • @Turing85 有没有办法告诉 Spring 将该类作为实现? (顺便说一句,是有可选的,但这只是我可以使用@Query的情况,但还有其他我不能使用的情况)
  • 我不知道。 Spring 尝试通过评估@(Native)Query-annotations 或SpEL-conventitons 自行在JpaRepository 中实现该方法。 --- 据我所知,Spring Data JAP 支持Optional
  • 我不希望@Transactional 出现在存储库界面上。相反,它应该继续服务类。
  • @K.Nicholas 我建议不要用@Transactional 注释整个服务类。更好的解决方案是仅注释实际需要事务语义的方法,并正确配置事务(例如,通过设置 readOnly = true 如果适用)。

标签: java spring hibernate jpa transactions


【解决方案1】:

Spring Data 对您如何命名事物很挑剔。根据documentation

与片段接口对应的类名中最重要的部分是Impl后缀。

换句话说,您需要调用类似SnapshotRepositoryExtra 的接口和实现SnapshotRepositoryExtraImpl 以便Spring Data 识别它(我见过的大多数示例将使用CustomSnapshotRepository 之类的接口作为接口,但我不要认为约定是必需的)。

这是最新版本;以前版本的 Spring Data 有different naming requirements

【讨论】:

  • 非常感谢,我一定会检查一下,因为你得到了我的 +1 啊哈
猜你喜欢
  • 1970-01-01
  • 2015-12-29
  • 2016-09-19
  • 2018-05-04
  • 1970-01-01
  • 2018-01-01
  • 2013-02-09
  • 2014-10-23
  • 1970-01-01
相关资源
最近更新 更多