首页 > 解决方案 > 如何将@NamedEntityGraph 与@EmbeddedId 一起使用?

问题描述

我正在尝试让 Spring Data JPA 使用连接发出一个查询以急切地获取实体图:

@Entity
@NamedEntityGraph(name = "PositionKey.all",
    attributeNodes = {@NamedAttributeNode("positionKey.account"),
        @NamedAttributeNode("positionKey.product")
    })

@Data
public class Position {

    @EmbeddedId
    private PositionKey positionKey;        
}

@Embeddable
@Data
public class PositionKey implements Serializable {

    @ManyToOne
    @JoinColumn(name = "accountId")
    private Account account;
    
    @ManyToOne
    @JoinColumn(name = "productId")
    private Product product;
}

这是我的 Spring Data 存储库:

public interface PositionRepository extends JpaRepository<Position, PositionKey> {

    @EntityGraph(value = "PositionKey.all", type = EntityGraphType.LOAD)
    List<Position> findByPositionKeyAccountIn(Set<Account> accounts);
    
}

这会产生以下异常:

 java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [positionKey.account] on this ManagedType

我希望在一个包含职位的联接语句中检索所有帐户和产品。如何执行此操作/引用嵌入的 ID 属性?

标签: springhibernatejpaspring-data-jpaspring-data

解决方案


如果可能的话,我建议以这种方式重构实体

@Entity
@NamedEntityGraph(name = "PositionKey.all",
attributeNodes = {@NamedAttributeNode("account"),
    @NamedAttributeNode("product")
})

@Data
public class Position {

    @EmbeddedId
    private PositionKey positionKey; 

    @MapsId("accountId")
    @ManyToOne
    @JoinColumn(name = "accountId")
    private Account account;
    
    @MapsId("productId")
    @ManyToOne
    @JoinColumn(name = "productId")
    private Product product;           
}

@Embeddable
@Data
public class PositionKey implements Serializable {

    @Column(name = "accountId")
    private Long accountId;
    
    @Column(name = "productId")
    private Long productId;
}

这样一个EmbeddedId更容易使用。例如,当您尝试通过id获取实体时,您不需要创建包含两个实体的复杂键。


推荐阅读