I am trying to write a JPA NamedQuery. I have a working SQL query as follows:
SELECT MIN(t1.Id + 1) AS nextID
FROM
MyTable t1 LEFT JOIN MyTable t2
ON
t1.Id + 1 = t2.Id
WHERE
t2.Id IS NULL
I am not able to translate this query to JPQL syntax.
I think doing such a custom join is not possible with standard JPQL. I was looking for a possibility to do it some time ago and found that Hibernate offers a proprietary extension @JoinFormula
to achieve this, cf. Hibernate @JoinFormula . But I couldn't find an equivalent for EclipseLink.
You might be able use a @NamedNativeQuery
together with an @SqlResultSetMapping
to map your SQL statement to a JPA entity, something like this:
@NamedNativeQuery( name = "customJoin",
query = "SELECT MIN(t1.Id + 1) AS nextID FROM MyTable t1 LEFT JOIN MyTable t2 ON t1.Id + 1 = t2.Id WHERE t2.Id IS NULL",
resultSetMapping = "customJoinMapping" )
@SqlResultSetMapping( name = "customJoinMapping",
entities = @EntityResult( entityClass = MyTable.class, fields = @FieldResult( name = "id", column = "nextID" ) ) )
@Entity
@Access( AccessType.Field )
public class MyTable {
private int id;
public int getId() {
return this.id;
}
public void setId( int id ) {
this.id = id;
}
}
UPDATE
Much later, I found a way to customize relationship joins in EclipseLink here . The feature to use is a DescriptorCustomizer
, which can be placed on a JPA entity with @Customizer
.
In the customize()
method, one can express additional join criteria using the EclipseLink Expression API. For example, the following code fragment would produce the additional join criteria [...] AND TargetEntity.someAttribute IN ('V', 'W', 'U')
(where someRelationship
points to a TargetEntity
).
OneToManyMapping mapping = (OneToManyMapping) descriptor.getMappingForAttributeName( "someRelationship" );
Expression origExp = mapping.buildSelectionCriteria();
ExpressionBuilder expBuilder = origExp.getBuilder();
Expression constantExp = expBuilder.get( "someAttribute" ).in( new String[] { "V", "W", "U" } );
Expression newExp = origExp.and( constantExp );
mapping.setSelectionCriteria( newExp );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.