Spring JPA嵌套投影生成了错误的查询

9

让我们考虑这些实体

@Entity
public class Room{

  @Id
  private Integer id;

  private String number;

  private String floor;

  @ManyToOne
  private RoomType roomType;

  // Setters & Getters  
}

@Entity
public class RoomType{

  @Id
  private Integer id;

  private String name;

  private String description;

  private Boolean enabled;

  // Setters & Getters  
}

同时还有这个与仓库类一起使用的投影接口。
public interface RoomList{

    public Number getId();

    public String getNumber();

    public RoomType getRoomType();

    interface RoomType {
        String getName();
    }   

}

@Repository
public interface RoomRepository extends JpaRepository<Room,Integer>{

    public Collection<RoomList> findAllProjectedBy();

}

现在,如果我查看生成的SQL。
select
    room0_.id as col_0_0_,
    room0_.number as col_1_0_,
    roomtype1_.id as id1_3_,
    roomtype1_.description as descript2_3_,
    roomtype1_.enabled as isActive3_3_,
    roomtype1_.name as name5_3_ 
from
    Room room0_ 
inner join
    roomType roomtype1_ 
        on room0_.roomType_id=roomtype1_.id

生成的查询应该类似于这样:
select
    room0_.id as col_0_0_,
    room0_.number as col_1_0_,
    roomtype1_.name as name5_3_ 
from
    Room room0_ 
inner join
    roomType roomtype1_ 
        on room0_.roomType_id=roomtype1_.id

有人能解释一下这种行为吗?或者这是一个bug吗?还有什么其他选项可以实现这种结果。我已经尝试过JPA entitygraph,但是在Hibernate中尚未完全支持图形类型获取,我也不想使用构造函数JPQL查询。谢谢!


findAllProjectedBy() 的作用与 findAll() 完全相同,只不过在 findAll() 中我只能返回 List<Room>,而在 findAllProjectedBy() 中我可以返回 List<RoomList> 或任何我想要的东西。 - belnxkkk
你有一个名为 RoomTypeinterface 和一个同名的 class,你考虑过将它们改变吗? - JB's
我有一个名为RoomType的类,但它不是一个接口。接口名称为RoomList,配置按照Spring Data JPA参考文档链接进行。需要创建RoomType内部接口以进行嵌套投影。 - belnxkkk
1
RoomType 内部接口是 Spring Data JPA 用于嵌套投影的必需接口,同时所有配置都正确。 - belnxkkk
将接口名称更改为“RoomTypeSummary”会导致运行时错误,因为在“Room”实体中没有指定名为“RoomTypeSummary”的字段。 - belnxkkk
显示剩余4条评论
1个回答

8
如果我理解正确,问题在于选择的属性/列比填充投影所需的更多。
正如我在问题DATAJPA-1218中所描述的那样,这就是目前Spring Data中投影工作的方式。引用实体的属性不会被限制为仅限于投影中使用的属性。

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