Java Spring数据JPA查询的行为异常
我有以下实体:Java Spring数据JPA查询的行为异常,java,spring-data-jpa,Java,Spring Data Jpa,我有以下实体: public class Order_status_sas { private Order_sas order; private Date lastModified; ... } public class Order_sas { private long id; ... } 我的积存: public interface StatusesWareHouseRepository extends CrudRepository<Order_stat
public class Order_status_sas {
private Order_sas order;
private Date lastModified;
...
}
public class Order_sas {
private long id;
...
}
我的积存:
public interface StatusesWareHouseRepository extends CrudRepository<Order_status_sas, Long> {
Order_status_sas findFirstByOrderIdOrderByLastModifiedDesc(long id);
}
此查询不返回一行,而是返回一列行。Spring数据似乎没有首先查看我的方法名称中的单词。还有一个例外:
org.springframework.dao.IncorrectResultSizeDataAccessException:
result returns more than one elements; nested exception is javax.persistence.NonUniqueResultException: result returns more than one elements
请告诉我我做错了什么,我怎样才能达到我的目的
编辑:
我使用自定义查询编辑了我的状态WarehouseRepository
:
@Query("select s from Order_status_sas s where s.order.id = ?1 order by s.lastModified desc limit 1")
Order_status_sas findFirstByOrderIdOrderByLastModifiedDesc(long id);
但是由Hibernate执行的查询没有改变。看起来是这样的:
select ...
from order_status_sas s
where s.order_id=?
order by s.last_modified desc
select ...
from clients c
order by c.name desc
您是否尝试过在FindFirstByOrderIDorDederByLastModifiedEsc(..)
方法的顶部添加@Query
注释(请参见)以手动指定预期行为?一个(不相关的)示例,说明了这一点的工作原理:
public interface InvoiceRepository extends JpaRepository<Invoice, Long> {
@Query("SELECT I FROM Invoice I JOIN I.customer C JOIN C.user U WHERE
U.username = :username")
public List<Invoice> findInvoicesByUsername(@Param("username")
String username);
}
公共接口InvoiceRepository扩展了JpaRepository{
@查询(“从发票中选择I I加入I.customer C加入C.user U WHERE
U.username=:用户名“)
公共列表findInvoicesByUsername(@Param(“用户名”)
字符串(用户名);
}
请注意,注释正文中使用的查询语言实际上不是SQL。有关@Query
注释的更多示例,请参阅Spring数据文档
PS:我对您的域对象结构也有矛盾的感觉,例如,Order\u sas
的实例是否真的应该存储在Order\u status\u sas
的实例中-应该是相反的吗?通常,您希望将引用对象存储在主域对象中,反之亦然。(不过,有一点可能是我做得不对。)
编辑:我甚至可以说,考虑到您当前的域模型,Hibernate做的一切都是正确的,只是缺少了一个限制1子句,将预期的结果集限制为一行。不过,查询本身效率极低,可以通过修复扭曲的域模型加以改进。好的,我理解@pridunemre point。让我们离开DB模型,回到JPA问题。下面是另一个例子:
@Entity
public class Client {
....
}
public interface ClientRepository extends CrudRepository<Client, Integer> {
Client findFirstByOrderByNameDesc();
}
如果我使用@Query
,当然我会达到预期的行为,但我想使用这种方法,因为根据文档,我可以达到这个目的。关于我的对象结构,我不同意你的看法。这是一对夫妻关系,一个订单有许多订单状态。我想知道我做错了什么,因为我的方法没有按照documentation.IMO中所述的那样运行。它运行不正确,因为您为它提供了一个非标准的域模型。当然,Order\u状态
也可以连接到多个订单
s?因此,你不再处理一对多的关系,而是多对多的关系。处理多对多关系的标准程序是,我相信您也知道,通过创建。因此,“标准”域模型将由以下内容组成:Order\u sas
,Order\u status\u link\u sas
(连接表),Order\u status\u sas
。请注意,Order\u status\u link\u sas
不是连接表的完美名称,而是一个简单的示例。通过一些猜测,你可能会想出一个更好、更有意义的名字。我真的不明白为什么我的模型是非标准的。请看,它完全如图所示:。请解释一下为什么你认为我在处理多对多关系?@polis:我想我已经对你的数据模型的错误给出了相当全面的解释。不过,让我再举一个例子:您提供的示例确实描述了一对多关系。对涉及的关系的口头描述是:“一名员工可以拥有多部电话;一部电话可以属于一名员工”。但是,在您的案例中,关系可以表述为:“一个订单可以由多个订单状态描述;一个订单状态可以归因于多个订单”。因此,您可以有效地创建多对多关系。实际上,它看起来就像Spring数据首先查看方法名称中的单词
,否则您将不会得到不正确的SultSizeDataAccessException
。如果您无法更改域模型,则可能必须使用条件
查询或手动查询。如前所述,此查询(以及上一个)中唯一缺少的是SQL限制1
子句。至于如何或是否可以实现这一点,希望对Spring的新特性有更广泛了解的人会来帮忙。不过,在此期间,您可以使用前面提到的一些解决方案和变通方法。
select ...
from clients c
order by c.name desc