java - 将 Java 泛型用于带有 WHERE 子句的 JPA findAll() 查询

标签 java generics jpa criteria-api

因此,经过 10 多年的休息后,我将回到 Java 并尝试使用 JPA 和 Java 泛型。我创建了一个基于泛型的 findAll(other) JPA 查询,它基本上可以执行

SELECT * FROM source WHERE other_id = other.id;

这就是我要去的地方。它有效,但我想知道是否有更好、更清洁的方法来做到这一点。使用 ManagedType 很困难,而且没有太多完整的文档或简单的示例。

我决定让我的代码尽可能通用(没有双关语意),所以我使用 JPA2。

这是所有实体类的根。我可能不需要它,但它可以防止我犯基本错误。

import java.io.Serializable;

public abstract class DomainObject implements Serializable {

    private static final long serialVersionUID = 1L;

    public abstract void setId(Long id);
    public abstract Long getId();

}

这是抽象的 DAO 类。我将其扩展为实现类,因为我需要更具体地执行其他 Activity - 主要是确保加载惰性集。

public abstract class GenericDAOImpl<T extends DomainObject, T2 extends DomainObject> implements GenericDAO<T, T2> {

private Class<T> type;

@PersistenceContext
protected EntityManager entityManager;

public GenericDAOImpl(Class<T> type) {
    super();
    this.type = type;
}

... save and delete classes go here

@Override
public List<T> findAll(T2 where) {

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type);
    Root<T> rootQuery = criteriaQuery.from(type);
    if (where != null) {

        EntityType<T> entity = entityManager.getMetamodel().entity(type);

        SingularAttribute<? super T, ?> attribute = null;
        for (SingularAttribute<? super T, ?> singleAttribute: entity.getSingularAttributes()) {
            // loop through all attributes that match this class
            if (singleAttribute.getJavaType().equals(where.getClass())) {
                // winner!
                attribute = singleAttribute;
                break;
            }
        }
        // where t.object = object.getID()
        criteriaQuery.where(criteriaBuilder.equal(rootQuery.get(attribute), where));
    }
    criteriaQuery.select(rootQuery);
    TypedQuery<T> query = entityManager.createQuery(criteriaQuery);

    // need this to make sure we have a clean list?
    // entityManager.clear();
    return query.getResultList();
}

有什么建议吗?如果有的话,我希望将其公开,以便其他人可以使用它。

最佳答案

如果您不想将 createQueryString 一起使用并且想要类型安全,请向 Adam Bien 致敬:

 @PersistenceContext
 EntityManager em;

 public List<ConfigurationEntry> allEntries() {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<ConfigurationEntry> cq = cb.createQuery(ConfigurationEntry.class);
        Root<ConfigurationEntry> rootEntry = cq.from(ConfigurationEntry.class);
        CriteriaQuery<ConfigurationEntry> all = cq.select(rootEntry);
        TypedQuery<ConfigurationEntry> allQuery = em.createQuery(all);
        return allQuery.getResultList();
 }

http://www.adam-bien.com/roller/abien/entry/selecting_all_jpa_entities_as

关于java - 将 Java 泛型用于带有 WHERE 子句的 JPA findAll() 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24572092/

相关文章:

java - 在简单的聚合 Storm 拓扑中分组

swift - 具有特定类型元素的 CollectionType 扩展会忽略子类型

java - 通用方法在分配给变量时返回正确的对象,但在与方法一起使用时不返回

java - EclipseLink 错误 : Entity class has no primary key specified. 它应该定义 @Id、@EmbeddedId 或 @IdClass

jpa - 域对象与 JPA 实体相同吗?

java - 我收到此错误 org.springframework.orm.jpa.EntityManagerHolder 无法转换为 org.springframework.orm.hibernate5.SessionHolder

java - 没有同步顺序的程序

java - JPA2/Hibernate - 即时创建模式(即无需手动预先创建模式)?

java - 如何创建不可编辑的 GXT ComboBox?

.net - 为什么运行时将泛型类型显示为 "GenericType` n"?