2

我有一组从单个超类继承的类:

   Super
     |
     +------+-------+
     Aaaa   Bbbb    Cccc

然后每个 Aaaa、Bbbb、Cccc 都应该包含方法 findByTag。问题是我无法笼统地定义它。以下示例为 Aaaa 定义了特定的 findByTag。

public interface AaaaRepository extends SuperRepository<Aaaa> {
    @Query("select distinct a from Aaaa a " +
            "join a.tags t " +
            "join fetch a.locale where t = ?1")
    public List<Event> findByTag(Tag t);
}

请注意,超类是@MappedSuperclass,并且在数据库中没有自己的表。

我想在查询中使用某种“超级”,它将在每个类中被其名称替换。

我的第二个问题是我不知道如何强制 @ElementCollection 被急切地获取。我必须始终在查询中明确地说“join fetch”。如果它没有被提取,一旦事务完成,我就无法访问那些我没有明确提取的对象。(LazyFetch 异常...)

谢谢

4

3 回答 3

2

查看文档,自定义实现部分,这种方法怎么样:

  1. 创建一个扩展存储库并具有您的 findByTag 方法的接口,没有注释。
  2. 创建该类的实现,并在方法实现中使用 JPA 标准。您还需要一个类字段来保存域对象的实际类,因为泛型在编译时会被删除。然后您使用该字段来构建标准。
  3. 阅读文档以将此实现用作存储库工厂的基类,然后 Spring Data 将基于此自定义构建其他存储库的实现。

    public interface MyRepository<T, ID> extends JpaRepository<T, ID> {        
        public List<Event> findByTag(Tag t);
    }
    
    public class MyRepositoryImpl<T, ID> implements MyRepository<T, ID> {
    
        private Class<T> actualClass; // initialized in the constructor
    
        public List<Event> findByTag(Tag t) {
             // here you build the criteria using actualClass field, and execute it.
        }
    }
    
    public interface AaaaRepository extends MyRepository <Aaaa, Integer> {
        // other methods...
    }
    

查看文档中的“Example 1.16. Custom repository factory bean”来创建工厂bean。

当 Spring 实例化 AaaaRepository 的实现时,它将使用 MyRepositoryImpl 作为基类。

这对你有用吗?

于 2012-02-09T19:39:44.653 回答
2

我不会这样写,而是创建一个类似于下面的伪 java 代码的数据访问对象:

class DAO<T> {
     private Class<T> clazz;
     DAO( Class<T> class) { this.clazz = t; }
     @PersistenceContext
     private EntityManager em;

     public List<T> findByTag(Tag t ) {
        Query q = em.createQuery( "select from " + clazz.getSimpleName + "....";
        ...
        return q.getResultList();
     }
}

希望能帮助到你!

于 2012-02-04T16:11:28.810 回答
0

最后,我对 Spring Data JPA 的行为和不灵活感到非常不满,因此我为自己编写了一个小工具,用于以简单的方式构建查询。使用示例如下:

https://github.com/knyttl/Maite/wiki/Maite-Persistence

有两个子类和定义功能的父类。但诀窍在于构建查询的流畅界面。

它只是在开始,但它已经起作用了,所以我没有重复和正确的继承。

父类的小例子 - 查看上面的链接了解详细信息:

@Autowired
EntityManager em;

protected abstract String getName();

protected Clause select() {
    return em
            .select("DISTINCT i")
            .from(this.getName(), "i")
            .joinFetch("i.locale lf")
}

public List<T> findByTag(Tag tag) {
    return (T) this.select()
            .join("i.tags t")
            .where("t = ?", tag)
            .fetchAll();
}
于 2012-02-15T22:56:33.350 回答