将 @EmbeddedId 与 JpaRepository 一起使用

Posted

技术标签:

【中文标题】将 @EmbeddedId 与 JpaRepository 一起使用【英文标题】:Using @EmbeddedId with JpaRepository 【发布时间】:2012-05-25 20:30:32 【问题描述】:

我有一个简单的实体类,带有 @EmbeddedIdIntegerString 字段在单独的类中)。我使用 Spring Data (org.springframework.data.jpa.repository.JpaRepository) 访问数据库 (mysql),使用正常的 Id 查询工作正常,包括 Spring 生成的和我自己编写的查询。使用EmbeddedId,我无法创建正确的查询。我想要做的是选择所有 id(发生某些条件的 embeddedId 字段之一)这里有一些代码示例,也许有人会知道如何解决它。 实体类:

@Entity
@Table(name="table_name")
public class EntityClass 

    @EmbeddedId
    private EmbeddedIdClass id;
    private String  someField;
    //rest of implemetation

EmbeddedId 类:

@Embeddable
public class EmbeddedIdClass implements Serializable 

public EmbeddedIdClass(Long id, String language) 
    super();
    this.id = id;
    this.language = language;


public UserAdTextId()         

@Column(name="ad_id", nullable=false)
    private Integer id;

    @Column(name="language_code", nullable=false)
    private String  language;
    //rest of implemetation

和存储库:

@Transactional(readOnly=true)
public interface MyRepository extends JpaRepository<EntityClass, EmbeddedIdClass> 
    @Query("select distinct ad_id from EntityClass where userId = :userId and (/*here the conditions*/)")
    public Page<Integer> findUserAdsWithSearchString(@Param("userId") Integer userId, @Param("searchString") String searchString, Pageable page);
//rest of implemetation

我没有找到任何文档如何创建支持 @EmbeddedId 的方法,我尝试了许多不同的方法名称,但我总是从方法解析器中得到异常。

【问题讨论】:

【参考方案1】:

(约西·列夫) 这可以通过以下方式完成: 假设您的主要实体是:

@Entity
@Table(name="JRULES_FLOW")
public class JrulesFlow implements Serializable 
   private static final long serialVersionUID = 1L;

   @EmbeddedId
   private JrulesFlowPK id;

   @Column(name="NEXT_SEQ")
   private int nextSeq;

   @Column(name="REF_ID")
   private String refId;

   @Column(name="TASK_TYPE")
   private String taskType;

   @Column(name="VALUE_TO_FIND")
   private String valueToFind;

你的PK课是:

@Embeddable
public class JrulesFlowPK implements Serializable 
   //default serial version id, required for serializable classes.
   private static final long serialVersionUID = 1L;

   @Column(name="FLOW_ID")
   private String flowId;

   @Column(name="TASK_SEQ")
   private long taskSeq;
 

JPA 存储库方法名称应包含 id 字段的名称 主类,后跟要在 PK 类中查询的属性:

public interface JrulesFlowRepository extends JpaRepository<JrulesFlow, 
      JrulesFlowPK>  // NOTE: put here both classes - also the pk class..
   public List<JrulesFlow>  findByIdFlowId(String flowId);  // Id - is the 
                  // @EmbeddedId in JrulesFlow. FlowId is an attribute 
                  // within JrulesFlowPK

【讨论】:

多列--findByIdCol1AndIdCol2AndIdCol3(String col1, String col2, String col3);作品【参考方案2】:

您的查询似乎使用了列名。它应该包含属性名称,包括嵌入对象的导航。这里还有一个相关的问题:How to write JPQL SELECT with embedded id?

select distinct id.id from EntityClass where userId = :userId and (...)

第一个id 引用EntityClassEmbeddedIdClass 类型)的属性id,第二个引用EmbeddedIdClassid 属性。

另外,请确保EntityClass 中有一个userId 属性。

【讨论】:

是的,我必须使用字段名称并浏览它们,但是我得到输出sql with seelct count(distinct...) 计数从哪里来??返回类型是 Page 或 List (我都在尝试... 答案还可以,我遇到的另一个问题是可分页...似乎具有 distinct 或 group by 的查询无法处理分页...可惜:(

以上是关于将 @EmbeddedId 与 JpaRepository 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring Data / Hibernate 级联保持 @OneToMany 与 @EmbeddedId 的关系

将 @EmbeddedId 表示为 H2 数据库的 SQL

带有@EmbeddedId 和@Embeddable 的EclipseLink 组合键

使用 @EmbeddedId 映射时出现 Eclipse 错误

休眠:@EmbeddedId、继承和@SecondaryTable

JPA - 标准 API 和 EmbeddedId