Отношение JPA/Hibernate @MappedSuperclass и @Inheritance(strategy = InheritanceType.JOINED)

У меня есть 3 таблицы, представленные моделью JPA. Первый:

@MappedSuperclass
public abstract class BaseEntity {
    @Id
    private Long id;
    private Boolean active;  
}

Следующий класс расширяет BaseEntity:

 @Entity
 @Inheritance(strategy = InheritanceType.JOINED)
 public abstract class Person extends BaseEntity{
    private String name;
 }

Последний — Student, который расширяет Person:

@Entity
public abstract class Student extends Person{
    private Integer grade;
}

Итак, у меня есть поле «активное» как в таблицах Person, так и в Student. Я хочу, чтобы, когда я обновляю поле «активно» через PersonRepository, оно также обновляло соответствующую строку в таблице Student. Пока он обновляет только таблицу Person. Является ли это возможным?


person Yuriy Gorbylov    schedule 08.09.2015    source источник
comment
Почему вы хотите дублировать актив в двух таблицах? У вас есть конкретный класс, который расширяет ученика?   -  person M4ver1k    schedule 08.09.2015
comment
Столбец active в таблице Student не должен существовать. Вы создали это сами или это было сгенерировано Hibernate?   -  person Predrag Maric    schedule 08.09.2015
comment
@Predrag Maric На самом деле он существует из-за MappedSuperclass.   -  person Yuriy Gorbylov    schedule 09.09.2015
comment
@ M4ver1k Я хочу иметь возможность фильтровать людей и студентов по активному полю. Но когда я обновляю активно в таблице Person, Student не обновляется. Вот почему у меня есть расхождение между этими таблицами.   -  person Yuriy Gorbylov    schedule 09.09.2015
comment
@YuriyGorbylov Хорошо, я бы не стал хранить Person и Student как отдельные таблицы в БД, но опять же это будет зависеть от ваших требований.   -  person M4ver1k    schedule 09.09.2015


Ответы (1)


Я нашел решение с аннотацией @Formula:

@Entity
public abstract class Student extends Person{

    @Formula("(SELECT p.active FROM person p WHERE p.id = id)")
    private Boolean active;
    private Integer grade;
}

И реализован метод, который обновляет «активное» поле в таблице Person вместо Student (я использую Spring Data):

public interface StudentRepository extends JpaRepository<Student, Long>{

    @Override
    @Query("update Person p set p.active = false where p.id = ?1")
    @Modifying
    @Transactional
    void deactivate(Long id);
}

@Formula возьмет «активное» значение Person и вставит его в Student с тем же идентификатором. В конце концов, «активное» поле Student вообще не будет использоваться, но я не могу избавиться от него из-за @MappedSuperclass.

person Yuriy Gorbylov    schedule 09.09.2015