JPA以通用方式命名Query getResultList()

时间:2016-12-30 11:27:09

标签: java generics jpa

我希望JPA命名查询的结果列表以List<ProjectLevel<?>>这样的通用方式。我需要这个,因为我想稍后再流式传输。

ProjectLevel是一个通用类。

public abstract class ProjectLevel<T extends ProjectLevel>{
....
}

按照建议添加ProjectLevel的子类。

@Entity
@Getter
@Setter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@Table(uniqueConstraints = {
    @UniqueConstraint(columnNames = {"businessAccountId", "id"})})
@NamedQueries({
    @NamedQuery(name = "Project.findByProjectIdOrUUID",
                query = "SELECT p FROM Project p WHERE (p.id = :id OR p.uuid = :id) and p.businessAccountId = :businessAccountId")
})
public class Project extends ProjectLevel {

    private static final long serialVersionUID = 2167149510293504460L;

    @Nonnull
    private String customerUUID;

    @Nonnull
    @Enumerated(EnumType.STRING)
    private Currency currency;

    @Nonnull
    @Enumerated(EnumType.STRING)
    private ProjectType projectType;

    @Nonnull
    @Enumerated(EnumType.STRING)
    private ContractType contractType;

    @Nonnull
    private String cityLocation;

    private boolean locationPermission;

    private boolean insuranceRequired;
}

我尝试了这个,但它给了我像

这样的类型转换错误
  

不兼容的类型:List<ProjectLevel>无法转换为   List<ProjectLevel<?>>

来自getResultList()行

    public List<ProjectLevel<?>> findUUIDByNameorNumber(@Nonnull final String nameOrId,
                                                        @Nonnull final String businessAccountId) {
        checkNotNull(nameOrId, "The nameOrId must not be null");

        return (List<ProjectLevel<?>>)getEntityManager()
                .createNamedQuery("ProjectLevel.findUUIDByNameOrId", ProjectLevel.class)
                .setParameter("name", matchesFromBeginning(nameOrId))
                .setParameter("businessAccountId", businessAccountId)
                .getResultList();
    }

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:0)

泛型类可能看起来像这样。

@Entity(name="ProjectLevel")
@Inheritance(strategy = InheritanceType.JOINED)
@NamedQuery(name="ProjectLevel.findAll", query="SELECT p FROM ProjectLevel p") 
public class ProjectLevel<T> implements Serializable {
   ...
}



@Entity
public class ProjectLevelString extends ProjectLevel<String>{

    String projectLevel;

}



@Entity
public class ProjectLevelInteger extends ProjectLevel<Integer>{

    Integer projectLevel;

}

您可以使用

选择所有ProjectLevel
List<ProjectLevel<?>> resultList = entityManager.createNamedQuery("ProjectLevel.findAll").getResultList();

答案 1 :(得分:0)

我不知道这是一个有效的解决方案,但是, 我通过从createNamedQuery中删除resultClass参数来解决这个问题。

  

resultClass - 查询结果的类型

此外,如果类型不匹配,它将抛出IllegalArgumentException。 来自doc:

  

IllegalArgumentException - 如果尚未使用   给定名称或者如果发现查询字符串无效或者是   发现查询结果不能分配给指定的类型

所以,我改变了我的方法。它现在工作正常。

@Nonnull
public List<ProjectLevel<?>> findUUIDByNameorNumber(@Nonnull final String nameOrId,
                                                    @Nonnull final String businessAccountId) {
    checkNotNull(nameOrId, "The nameOrId must not be null");

    return getEntityManager()
            .createNamedQuery("ProjectLevel.findUUIDByNameOrId")
            .setParameter("name", matchesFromBeginning(nameOrId))
            .setParameter("businessAccountId", businessAccountId)
            .getResultList();
}