使用实体类型表达式的Spring数据JPA [英] Spring data JPA using Entity Type expression

查看:139
本文介绍了使用实体类型表达式的Spring数据JPA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Spring数据JPA仓库 @Query 中使用JPA 2.0 Type表达式,但它给我一个验证错误验证失败查询方法public abstract java.util.List my.org.FooRepository.findAllByRoomCode()!



这是我的实体定义:



继承:

  @Entity(name =Location)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class LocationEntity {

@Column(name =CODE)
保护字符串代码;

@OneToMany(mappedBy =location)
protected List< LampEntity>灯=新的ArrayList< LampEntity>();
...
}

@Entity(name =Floor)
@Table(name =FLOOR,uniqueConstraints = {
@ UniqueConstraint(name =FLOOR_UK,columnNames =CODE)
})
public class FloorEntity extends LocationEntity {
...
@OneToMany(mappedBy =floor)
私人列表< RoomEntity> rooms = new ArrayList< RoomEntity>();
...
}

@Entity(name =Room)
@Table(name =ROOM,uniqueConstraints = {
@ UniqueConstraint(name =ROOM_UK,columnNames = {CODE,FLOOR_ID})
})
public class RoomEntity extends LocationEntity {
...
@ManyToOne
@JoinColumn(name =FLOOR_ID,nullable = false,referencedColumnName =ID)
私人FloorEntity楼层;
...
}

请求实体:

  @Entity(name =Lamp)
@Table(name =LAMP)
public class LampEntity {

@ManyToOne
@JoinColumn(name =LOCATION_ID,referencedColumnName =ID)
私人LocationEntity位置;

存储库:

  public interface LampRepository扩展JpaRepository< LampEntity,Long> {

@query(选择指示灯从指示灯指示灯WHERE lamp.location.code =:locationCode AND TYPE(指示灯位置)=指示灯)
public List< LampEntity> findAllByRoomCode(@Param(code)String locationCode);
...
}

我正在使用 spring-data-JPA 1.4.1.RELEASE Hibernate 4.2.7.Final 作为提供者。



我的问题是:


  1. 是否可以使用Spring数据JPA来完成这项工作?

  2. 在一个旧的stackoverflow文章中,我发现Hibernate只接受了 InheritanceType.SINGLE_TABLE ,但现在可以在4.2.7中正常运行了吗?

  3. 如果不是,如果我想保留 InheritanceType.TABLE_PER_CLASS 策略,我有什么选择?

非常感谢




更新了独特的约束和楼层房间

解决方案

我的错误,我误解了一些事情,并没有完整地阅读stacktrace:


  1. 错误不属于Spring Data,但是休眠。由引起的真正 org.hibernate.QueryException:无法解析属性:class of:xxx.yyy.LampEntity [SELECT lamp FROM xxx.yyy .LampEntity lamp WHERE lamp.location.code =:locationCode AND TYPE(lamp.location)= Room]

  2. 作为属性显然是在这里命名的,我运行了一些有效性测试(下面的请求完全是函数不正确的,只是语法):

@Query(SELECT lamp FROM Lamp lamp WHERE lamp.location.code =:code AND TYPE(lamp)= Lamp) failed ,同样的堆栈跟踪

@Query(SELECT lamp FROM Lamp lamp WHERE lamp.location.code =:code AND lamp.location.class = Room )确定,工作正常,返回预期结果(仅限具有房间位置的灯)



创建了一个新的Repository public interface LocationRepository扩展了JpaRepository< LocationEntity,Long> 并且我测试了:


$ b

@Query(SELECT location FROM Location location WHERE TYPE(location)= Room AND location.code =:code) OK ,正常工作。



因此,我将使用 lamp.location.class (Hibernate specific :()因为看起来Hibernate(或JPA?)不允许在HQL请求中使用TYPE或属性,也不允许没有继承的实体(相当逻辑的这一个)。

请让我知道这个答案是否有补充或更正。


I would like to use the JPA 2.0 Type expression in a spring data JPA repository @Query but it give me a validation error Validation failed for query for method public abstract java.util.List my.org.FooRepository.findAllByRoomCode()!.

Here is my entities definition :

inherited :

@Entity(name = "Location")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class LocationEntity {

    @Column(name = "CODE")
    protected String code;

    @OneToMany(mappedBy = "location")
    protected List<LampEntity> lamps = new ArrayList<LampEntity>();
        ...
}

@Entity(name = "Floor")
@Table(name = "FLOOR", uniqueConstraints = {
    @UniqueConstraint(name = "FLOOR_UK", columnNames = "CODE")
})
public class FloorEntity extends LocationEntity {
    ...
    @OneToMany(mappedBy = "floor")
    private List<RoomEntity> rooms = new ArrayList<RoomEntity>();
    ...
}

@Entity(name = "Room")
@Table(name = "ROOM", uniqueConstraints = {
    @UniqueConstraint(name = "ROOM_UK", columnNames = { "CODE", "FLOOR_ID" })
})
public class RoomEntity extends LocationEntity {
    ...
    @ManyToOne
    @JoinColumn(name = "FLOOR_ID", nullable = false, referencedColumnName = "ID")
    private FloorEntity floor;
    ...
}

requested entity :

@Entity(name = "Lamp")
@Table(name = "LAMP")
public class LampEntity {

    @ManyToOne
    @JoinColumn(name = "LOCATION_ID", referencedColumnName = "ID")
    private LocationEntity location;
}

repository :

public interface LampRepository extends JpaRepository<LampEntity, Long> {

    @Query("SELECT lamp FROM Lamp lamp WHERE lamp.location.code = :locationCode AND TYPE(lamp.location) = Room")
    public List<LampEntity> findAllByRoomCode(@Param("code") String locationCode);
    ...
}

I'm using spring-data-JPA 1.4.1.RELEASE with Hibernate 4.2.7.Final as provider.

My questions are :

  1. Is it possible to do that with Spring data JPA ?
  2. In a old stackoverflow post i saw that Hibernate accepted it only with InheritanceType.SINGLE_TABLE but maybe now it's ok in 4.2.7 ?
  3. If not, what are my alternative if I want to keep my InheritanceType.TABLE_PER_CLASS strategy ?

Thanks a lot


Updated with unique constraints and relation between Floor and Room

解决方案

OK, my mistake, I have misunderstood a couple of things and not read fully the stacktrace :

  1. The error doesn't belong to Spring Data but to Hibernate. The real Caused by is org.hibernate.QueryException: could not resolve property: class of: xxx.yyy.LampEntity [SELECT lamp FROM xxx.yyy.LampEntity lamp WHERE lamp.location.code = :locationCode AND TYPE(lamp.location) = Room]
  2. As the property class is clearly named here, I ran a couple of tests of validity (the requests below are totally functionnaly incorrect, it's just for the syntax) :

@Query("SELECT lamp FROM Lamp lamp WHERE lamp.location.code = :code AND TYPE(lamp) = Lamp") fails, same stacktrace

@Query("SELECT lamp FROM Lamp lamp WHERE lamp.location.code = :code AND lamp.location.class = Room") OK, works correctly, the expected results are returned (only the lamps which have a room's location)

I Created a new Repository public interface LocationRepository extends JpaRepository<LocationEntity, Long> and I tested :

@Query("SELECT location FROM Location location WHERE TYPE(location) = Room AND location.code = :code") OK, works correctly.

So I'll go with the lamp.location.class (Hibernate specific :() because it seems Hibernate (or JPA ?) doesn't allow to TYPE nor an attribute in an HQL request, neither an entity which is not inherited (pretty logic this one).

Please let me know if there is any complement or correction to this answer.

这篇关于使用实体类型表达式的Spring数据JPA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆