【问题标题】:How to implement database inheritance in Spring Data JPA with MapperSuperClass?如何使用 MapperSuperClass 在 Spring Data JPA 中实现数据库继承?
【发布时间】:2016-12-11 20:39:42
【问题描述】:

我正在 Spring Data JPA 中尝试 JOINED 类型的数据库继承,参考 this article。这工作得很好。但我必须在我的项目中实现MappedSuperClass。我通过以下方式实现:

Base.java

@MappedSuperclass
public abstract class Base {
    public abstract Long getId();
    public abstract void setId(Long id);
    public abstract String getFirstName();
    public abstract void setFirstName(String firstName);
}

BaseImpl.java

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class BaseImpl extends Base {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String firstName;

    ...
}

Super1.java

@MappedSuperclass
public abstract class Super1 extends BaseImpl {
    public abstract String getSuperName();
    public abstract void setSuperName(String guideName);
}

Super1Impl.java

@Entity
public class Super1Impl extends Super1 {
    private String superName;

    ...
}

BaseBaseRepository.java

@NoRepositoryBean
public interface BaseBaseRepository<T extends Base> extends JpaRepository<T, Long> { }

BaseRepository.java

@NoRepositoryBean
public interface BaseRepository<T extends Base> extends BaseBaseRepository<Base> { }

BaseRepositoryImpl.java

@Transactional
public interface BaseRepositoryImpl extends BaseRepository<BaseImpl> { }

Super1Repository.java

@NoRepositoryBean
public interface Super1Repository<T extends Super1> extends BaseBaseRepository<Super1> { }

Super1RepositoryImpl.java

@Transactional
public interface Super1RepositoryImpl extends Super1Repository<Super1Impl> {  }

我正在尝试在测试用例中保存 Super1 对象:

@Test
public void contextLoads() {
    Super1 super1 = new Super1Impl();
    super1.setSuperName("guide1");
    super1.setFirstName("Mamatha");
    super1.setEmail("jhhj");
    super1.setLastName("kkjkjhjk");
    super1.setPassword("jhjjh");
    super1.setPhoneNumber("76876876");

    System.out.println(super1Repository.save(super1));
}

但我收到以下错误:

Caused by: org.springframework.beans.factory.BeanCreationException:
  Error creating bean with name 'baseRepositoryImpl':
    Invocation of init method failed; nested exception is java.lang.IllegalArgumentException:
      This class [class com.example.entity.Base] does not define an IdClass
.....
Caused by: java.lang.IllegalArgumentException: This class [class com.example.entity.Base] does not define an IdClass
.......

Super1Impl 中尝试了@PrimaryKeyJoinColumn(name = "id", referencedColumnName = "id"),但仍然出现同样的错误。

【问题讨论】:

    标签: spring-data-jpa multiple-inheritance mappedsuperclass


    【解决方案1】:

    错误是由不正确的存储库接口声明引起的。

    BaseRepository<T extends Base> extends BaseBaseRepository<Base>
    

    应该是

    BaseRepository<T extends Base> extends BaseBaseRepository<T>
    

    Super1Repository<T extends Super1> extends BaseBaseRepository<Super1>
    

    应该是

    Super1Repository<T extends Super1> extends BaseBaseRepository<T>
    

    正如当前声明的那样,BaseBaseRepository&lt;Base&gt; 表示 Base 对象的存储库,Base 没有 @Id 字段,因此出现错误。

    【讨论】:

    • 我保留了除 BaseRepository 和 Super1Repository 之外的所有代码。当我在保存后收到对象时,我希望它是 Super1 类型。存储库中没有提及它。请帮忙。
    • 我不明白你的评论。 Here 是我更正的示例项目。您可以以mvn clean test 的身份运行单元测试,以查看然后运行良好。如果你把代码改成你原来的代码,你在问题中提到的错误会立即弹出。
    • 有没有办法创建通用存储库,我们不需要为每个实体创建存储库?
    • @VinitSolanki,是的,只要您使用 EclipseLink 或 OpenJPA 作为 JPA 提供程序。 Hibernate 存在阻止使用通用存储库的错误。详情请见this answer
    猜你喜欢
    • 2012-05-18
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    相关资源
    最近更新 更多