【问题标题】:Writing CRUDRepository's findBy() method on a field annotated by JoinColumn在由 JoinColumn 注释的字段上编写 CRUDRepository 的 findBy() 方法
【发布时间】:2015-05-01 10:59:05
【问题描述】:

我对 Spring JPA 有点陌生,所以如果我的问题听起来很基础,我提前道歉。我有 2 个实体对象:OrderInfo 和 PersonInfo。类如下:

@Entity
@Table(name="order_info")
@NamedQuery(name="OrderInfo.findAll", query="SELECT o FROM OrderInfo o")
public class OrderInfo implements Serializable {

    @Column(name="order_number")
    private String orderNumber;

    //bi-directional many-to-one association to PersonInfo
    @ManyToOne
    @JoinColumn(name="person_id")
    private PersonInfo personInfo;

    public String getOrderNumber() {
        return this.orderNumber;
    }

    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }

    public PersonInfo getPersonInfo() {
        return this.personInfo;
    }

    public void setPersonInfo(PersonInfo personInfo) {
        this.personInfo = personInfo;
    }


}

还有 Person 实体:

@Entity
@Table(name="person_info")
@NamedQuery(name="PersonInfo.findAll", query="SELECT p FROM PersonInfo p")
public class PersonInfo implements Serializable {

    //bi-directional many-to-one association to OrderInfo
    @OneToMany(mappedBy="personInfo")
    private List<OrderInfo> orderInfos;

    public List<OrderInfo> getOrderInfos() {
        return this.orderInfos;
    }

    public void setOrderInfos(List<OrderInfo> orderInfos) {
        this.orderInfos = orderInfos;
    }

    public OrderInfo addOrderInfo(OrderInfo orderInfo) {
        getOrderInfos().add(orderInfo);
        orderInfo.setPersonInfo(this);

        return orderInfo;
    }

    public OrderInfo removeOrderInfo(OrderInfo orderInfo) {
        getOrderInfos().remove(orderInfo);
        orderInfo.setPersonInfo(null);

        return orderInfo;
    }

}

这两个类是在 Eclipse 中使用 JPA 的 create entityfromtable 选项自动生成的。

现在,我正在尝试编写一个 CRUDRepository 来获取给定 orderNumber 和 personId 的 OrderInfo。如果我在 OrderInfo 对象中有一个 personId 字段,我可以编写类似

的内容
@Repository
public interface OrderRepository extends CrudRepository<OrderInfo, Integer>{
    public OrderInfo findByPersonIdAndOrderNumber(@Param("personId") Long personId, @Param("orderNumber") String orderNumber);

}

但是,现在 OrderInfo 实体没有 personId。相反,它具有对 Person 的引用(同样,我没有编写实体类。它们是由 Eclipse 自动生成的)。现在应该怎么写 findBy() 方法?

提前致谢。

【问题讨论】:

    标签: spring jpa spring-data-jpa


    【解决方案1】:

    我找到了另一个解决方案,假设我们有一个用户实体和消息实体。

    @Entity
    public class Message {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @NotNull
        @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
        private DateTime date;
    
        @ManyToOne
        @JoinColumn(name = "id_user_sender")
        private User userSender;
    
        @NotNull
        private Long idUserReceiver;
    
        @NotNull
        @Length(min = 10)
        private String message;
    
        @NotNull
        private String idConversation;
    
        @NotNull
        Boolean userHasRead;
    
        //Getters and Setters
    
    }
    
    
    
    @Entity
    public class User implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        //Some other properies like email,name etc
        //Getters and setters
    }
    

    现在我需要通过 id_user_sender 查找所有消息。

    public interface MessageRepository extends JpaRepository<Message,Long>,TransactionRepositoryCustom {
        List<Message> findByUserSenderId(Long idUser);
    }
    

    解释: 在消息实体中,我有一个名为“userSender”的用户对象。 userSender 有一个名为“id”的字段。

    所以 'findByUserSenderId' 在 userSender 对象中搜索 id。

    另一种可能性是将完整的用户对象传递给消息存储库,如下例所示:(用户对象必须只包含 id)

    public interface MessageRepository extends JpaRepository<Message,Long>,TransactionRepositoryCustom {
       List<Message> findByUserSender(User user);
    }
    

    【讨论】:

    • 此解决方案因“无法在此 ManagedType [...] 上找到具有给定名称 blablaId 的属性而失败”
    • 这对我有用。确保字段是驼峰式的。
    • 另外,如果上述方法不起作用,请尝试使用下划线解决此歧义findByUserSender_Iddocs.spring.io/spring-data/jpa/docs/current/reference/html/…
    【解决方案2】:

    使用 JPQL 查询:

    @Query("select o from OrderInfo o where o.orderNumber = :orderNumber"
           + " and o.personInfo.id = :personId")
    

    【讨论】:

    • 谢谢。但我不想使用手动 JPQL。单独写方法定义就没有别的办法了吗?
    • 如果某些东西有效,它必须是 findByPersonInfoIdAndOrderNumber(),因为您的字段是名称 personInfo 而不是 person。但实际上,您应该更喜欢可读的方法名称。编写这样一个微不足道的查询并不难。
    【解决方案3】:

    我认为您需要更新 spring data jpa 版本。 我目前正在使用 spring-data-jpa-2.0.2.RELEASE 并且效果很好。

    此外,它适用于这两种情况。 您可以将您的接口方法定义为 -

    List<Message> findByUserSender(User user);
    

    或 -

    List<Message> findByUserSenderId(Long idUser);
    

    这两种方法都会在 user_sender 表上创建一个左外连接以获取所需的消息;

    【讨论】:

      【解决方案4】:

      我相信这就是您要寻找的: Spring Data JPA - Repositories - Property expressions

      对于您的代码,这可能有效(我没有尝试过):

      public OrderInfo findByPersonInfoIdAndOrderNumber(Long personInfoId, String orderNumber);

      【讨论】:

        猜你喜欢
        • 2020-03-29
        • 2018-06-10
        • 1970-01-01
        • 2018-06-02
        • 2020-01-31
        • 1970-01-01
        • 1970-01-01
        • 2015-12-24
        相关资源
        最近更新 更多