Spring数据JPA使用实体类型表达式

时间:2014-07-08 07:59:53

标签: java hibernate jpa jpa-2.0 spring-data-jpa

我想在spring数据JPA存储库@Query中使用JPA 2.0 Type表达式,但它给出了验证错误Validation failed for query for method 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")
    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;
    ...
}

请求的实体:

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

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

存储库:

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);
    ...
}

我使用spring-data-JPA 1.4.1.RELEASEHibernate 4.2.7.Final作为提供商。

我的问题是:

  1. 可以使用Spring数据JPA吗?
  2. 在一个旧的stackoverflow帖子中,我看到Hibernate仅用InheritanceType.SINGLE_TABLE接受了它,但现在它可能在4.2.7中没问题了吗?
  3. 如果没有,如果我想保留InheritanceType.TABLE_PER_CLASS策略,我还有什么选择?
  4. 非常感谢


    使用了FloorRoom

    之间的唯一约束和关系进行了更新

2 个答案:

答案 0 :(得分:1)

如果您使用Spring JPA存储库,则可以通过将方法重命名为@Query来执行此操作:

public List<LampEntity> findByLocation_Code(@Param("code") String locationCode);

确保所有的安装人员和吸气人员都到位。

答案 1 :(得分:0)

好吧,我的错误,我误解了一些事情而没有完全阅读堆栈跟踪:

  1. 错误不属于Spring Data,而属于Hibernate。真正的Caused byorg.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. 由于属性class在此明确命名,我进行了几项有效性测试(下面的请求完全不正确,只是语法):
  3. @Query("SELECT lamp FROM Lamp lamp WHERE lamp.location.code = :code AND TYPE(lamp) = Lamp")失败,同样的堆栈跟踪

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

    我创建了一个新的存储库public interface LocationRepository extends JpaRepository<LocationEntity, Long>,我测试了:

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

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

    如果对此答案有任何补充或更正,请与我们联系。