在一个被JoinColumn注释的字段上编写CRUDRepository的findBy()方法

23

我对Spring JPA还比较陌生,所以如果我的问题听起来很基础,我先道歉了。我有两个实体对象: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来获取给定订单编号和人员ID的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()方法呢?

先感谢您的帮助。

4个回答

20
我找到了另一个解决方案,假设我们有一个用户实体和一个消息实体。
@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);
}

1
这个解决方案对我来说失败了,出现了“在此ManagedType上无法找到具有给定名称blablaId的属性”的错误。 - gustavohenke
这对我有用。确保字段采用驼峰式命名。 - Ikechukwu Eze
另外,如果上述方法无法解决歧义,请尝试使用下划线:findByUserSender_Id。参考链接:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions - skryvets

4

我认为你需要更新Spring Data JPA版本。我目前正在使用spring-data-jpa-2.0.2.RELEASE,它运行良好。

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

List<Message> findByUserSender(User user);

或者 -
List<Message> findByUserSenderId(Long idUser);

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


4

使用JPQL查询:

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

谢谢。但我不想使用手动JPQL。难道没有其他方法只通过编写方法定义来完成吗? - drunkenfist
如果有什么东西是有效的,那一定是findByPersonInfoIdAndOrderNumber(),因为您的字段是personInfo而不是person。但是,你真的应该偏爱可读性强的方法名称。编写这样一个琐碎的查询并不难。 - JB Nizet

2
我相信这是您要寻找的内容: Spring Data JPA - Repositories - 属性表达式 对于您的代码,以下可能有效(我没有试过): public OrderInfo findByPersonInfoIdAndOrderNumber(Long personInfoId, String orderNumber);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接