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 :
- Is it possible to do that with Spring data JPA ?
- 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 ? - 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
If you use Spring JPA repository, you can do this without
@Query
by renaming the method as:Just make sure all your setters and getters are in place.
OK, my mistake, I have misunderstood a couple of things and not read fully the stacktrace :
Caused by
isorg.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]
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.