Как реализовать наследование базы данных в Spring Data JPA с помощью MapperSuperClass?

Я пробую наследование базы данных типа JOINED в Spring Data JPA, ссылаясь на этой статьи. Это сработало нормально. Но я должен реализовать 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
.......

Пробовал @PrimaryKeyJoinColumn(name = "id", referencedColumnName = "id") в Super1Impl, но все равно получаю ту же ошибку.


person User1230321    schedule 11.12.2016    source источник


Ответы (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<Base> означает хранилище объектов Base, а Base не имеет поля @Id, отсюда и ошибка.

person manish    schedule 12.12.2016
comment
Я сохранил весь свой код, кроме BaseRepository и Super1Repository. Когда я получаю объект после его сохранения, я хочу, чтобы он имел тип Super1. В Репозитории об этом не упоминается. Пожалуйста помоги. - person User1230321; 15.12.2016
comment
Я не понимаю вашего комментария. Вот пример проекта с моими исправлениями. Вы можете запустить модульные тесты как mvn clean test, чтобы увидеть, а затем работать нормально. Если вы измените код на свой исходный код, сразу же появится ошибка, о которой вы упомянули в вопросе. - person manish; 15.12.2016
comment
Есть ли способ создать общий репозиторий, нам не нужно создавать репозиторий для каждого объекта? - person Vinit Solanki; 14.04.2017
comment
@VinitSolanki, да, если вы используете EclipseLink или OpenJPA в качестве поставщика JPA. В Hibernate есть ошибки, которые не позволяют использовать общий репозиторий. Подробности см. в этом ответе. - person manish; 14.04.2017