spring-data-jpa 是否有一种方法可以检索具有列表属性的实体,但加载具有最后几个实体的列表?

waxmsbnn  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(107)

假设我的应用程序中有以下实体:

@Data
@Entity
public class SomeEntity {
    @Id
    private Long id;

    @OneToMany
    private List<AnotherEntity> anotherEntities = new ArrayList<>();

    @Version
    private Long version;

}

@Data
@Entity
public class AnotherEntity {
    @Id
    private Long id;

    @Column
    private String someField;

    @Column
    private Long version;

}

问题1:

例如,我想加载一个id = 1的SomeEntity,但我只想部分加载另一个实体,例如,我只想加载它的最后10个版本,用一个请求完成此操作(使用Hibernate/Spring Data JPA)的最简单和最直接的方法是什么?

问题2:

我想更新前面提到的对象并添加一个新的AnotherEntity到列表中,但是JpaRepository的保存(T t)方法保存了整个对象,我丢失了没有加载的对象。我如何保存对象,以便Spring Data(乐观锁定)更新版本,并且SomeEntity不会丢失以前的数据?

更新1:

我正在使用Postgresql的数据库。

thigvfpy

thigvfpy1#

根据您的确切约束,您有不同的选项。

您可以使用@Where注解:

@Data
@Entity
public class SomeEntity {
    @Id
    private Long id;

    @OneToMany
    @Where(clause = "version < 10")
    private List<AnotherEntity> anotherEntities = new ArrayList<>();

    @Version
    private Long version;

}

您可以使用过滤器:

@Data
@Entity
public class SomeEntity {
    @Id
    private Long id;

    @OneToMany
    @Filter(
        name="latestVersions",
        condition="version < :version"
   )
   private List<AnotherEntity> anotherEntities = new ArrayList<>();

}

您可以在使用会话运行查询之前启用筛选器:

entityManager
    .unwrap(Session.class)
    .enableFilter("latestVersions")
    .setParameter("version", 10);

List<Account> accounts = entityManager.createQuery(
    "from SomeEntity se where se.id = 1", SomeEntity.class)
.getResultList();

您可以将关联Map为双向(或多对一)

@Data
@Entity
public class SomeEntity {
    @Id
    private Long id;

    @OneToMany(mappedBy = "someEntity")
    private List<AnotherEntity> anotherEntities = new ArrayList<>();

    @Version
    private Long version;

}

@Data
@Entity
public class AnotherEntity {
    @Id
    private Long id;

    @Column
    private String someField;

    @Column
    private Long version;

   @ManyToOne
   private SomeEntity someEntity;
}

现在您可以使用HQL查询来获取实体列表:

from AnotherEntity ae where ae.someEntity.id = 1 and ae.version < 10

当你想创建一个新的AnotherEntity时,你可以从结果列表中的任何元素中获取SomeEntity,或者你可以使用EntityManager#getReference(并且避免运行查询):

AnotherEntity ae = new AnotherEntity(...);
ae.setSomeEntity(em.getReference(SomeEntity.class, 1));
em.persist(ae);

关联是惰性的,因此Hibernate不会加载整个集合(除非您需要访问它)。

相关问题