Spring动态JPA存储库类型

时间:2017-07-19 09:21:16

标签: java spring hibernate spring-data-jpa

我需要从XML文件填充大约30个表。我想为此目的使用JPA。

现在我有30个用@Entity注释的类,用于扫描实体和存储库的配置;

我也有:

@Repository
public interface MyRepository extends JpaRepository<MyEntity1, Long> {
}

和(某些控制者):

@Autowired
public MyRepository myRepository;
...
...
MyEntity1 entity = new MyEntity(...);
myRepository.save(entity);

它适用于一个@Entity,但我应该为此定义30个存储库吗?

我以为我可以这样做:

@Repository
public interface MyRepository<T> extends JpaRepository<T, Long> {
}

然后:

@Autowired
public MyRepository<MyEntity1> myRepository1;
@Autowired
public MyRepository<MyEntity2> myRepository2;

但是这出错了:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myRepository1': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object

3 个答案:

答案 0 :(得分:3)

不幸的是,你不能这样做,你将不得不写30个单独的存储库。但是,当实体共享单个表继承时,您可以编写通用存储库。 (参见Using generics in Spring Data JPA repositories的答案)

您的代码尝试做的是创建一个存储库,其中共享继承在Object类上,而不是@Entity,因此是例外。

另外一个小注释,您不需要使用@Repository注释您的存储库。如果配置正确,Spring数据会自动将它们注册为bean。

答案 1 :(得分:3)

尝试这种方法:

所有实体的基类

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;
}

<强>实体

@Entity
public class Entity1 extends BaseEntity {

    private String name;
}

@Entity
public class Entity2 extends BaseEntity {

    private String name;
}

常见的回购

public interface BaseEntityRepo extends JpaRepository<BaseEntity, Long> {
}

<强>用法

public class BaseEntityRepoTest extends BaseTest {

    @Autowired
    private BaseEntityRepo repo;

    @Test
    public void baseEntityTest() throws Exception {

        BaseEntity entity1 = new Entity1("entity1");
        BaseEntity entity2 = new Entity2("entity2");

        repo.save(entity1);
        repo.save(entity2);

        List<BaseEntity> entities = repo.findAll();
        assertThat(entities).hasSize(2);

        entities.forEach(System.out::println);
    }
}

答案 2 :(得分:2)

据我所知,你所尝试的是不可能的。 Spring Data JPA需要每个Entity类型的接口用于其存储库,因为Spring Data JPA将创建query implementations

因此建议您拥有每个实体的存储库,因为它将允许您在将来添加复杂的findByXXX方法。