将SQL Left Join查询转换为EclipseLink JPA查询

时间:2015-04-15 20:40:30

标签: java jpa eclipselink jpql

我正在尝试编写JPA NamedQuery。我有一个有效的SQL查询,如下所示:

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

我无法将此查询转换为JPQL语法。

1 个答案:

答案 0 :(得分:1)

我认为使用标准JPQL无法进行此类自定义连接。我之前正在寻找一种可能性,并发现Hibernate提供了专有扩展@JoinFormula来实现这一目标,参见Hibernate @JoinFormula。但我找不到EclipseLink的等价物。

您可以使用@NamedNativeQuery@SqlResultSetMapping将SQL语句映射到JPA实体,如下所示:

@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;
   }
}

<强> 更新

很久以后,我找到了一种在EclipseLink here中自定义关系连接的方法。要使用的功能是DescriptorCustomizer,可以使用@Customizer放置在JPA实体上。

customize()方法中,可以使用EclipseLink Expression API表达其他连接条件。例如,以下代码片段将生成其他连接条件[...] AND TargetEntity.someAttribute IN ('V', 'W', 'U')(其中someRelationship指向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 );