У нас есть user
таблицы таблиц, который развился совсем немного, и мы не хотим загружать унаследованных пользователей в приложение. Устаревший пользователь идентифицируется user_type
.
Если я использую следующее отображение, то все работает так, как ожидалось:
@Entity
@Table(name="user")
@Where("user_type = 2") // 1 is legacy
class User {
@Column(name="user_type")
int type;
}
Мне нужно отображать таблицу user
несколько раз, и я хочу оставаться СУХОЙ. Поэтому я подумал, что могу извлечь бит @Where
в суперкласс и наследовать его так:
@Where("type = 2") // 1 is legacy
abstract class BaseUser {
}
@Entity
@Table(name="user")
class User extends BaseUser {
}
У меня есть следующий тест (я надеюсь, что он достаточно понятен), который терпит неудачу:
@Test
@DbUnitData("legacy_user.xml") // populates DB with 1 user (id=1) with type=1
public void shouldNotGetLegacyUser() {
assertThat(em.find(User.class, 1L)).isNull();
}
Есть ли способ наследования класса с аннотацией Hibernate @Where
?
То, что вы действительно ищете, это не @Where, а @DiscriminatorColumn и @DiscriminatorValue. Эти аннотации позволяют сопоставлять два объекта @Entity с одной таблицей на основе @DiscriminatorColumn.
В руководстве Hibernate имеется параграф: Сопоставление наследования
В основном вы создадите суперкласс, BaseUser и два подкласса LegacyUser и User:
@Entity
@Table(name = "COM_ORDER")
@DiscriminatorColumn(name = "COM_ORDER_TYPE", discriminatorType = DiscriminatorType.INTEGER)
public class BaseUser {
@Id
private Long id;
<Enter your generic columns here, you do not need to add the user_type column>
}
@Entity
@DiscriminatorValue("1")
public class LegacyUser extends BaseUser {
<Enter your legacy specific fields here>
}
@Entity
@DiscriminatorValue("2")
public class LatestUser extends BaseUser {
<Enter your new and improved user fields here>
}
С помощью этой установки вы можете легко расширить количество пользовательских типов, создав новые классы, которые расширяют класс BaseUser. Вы должны иметь в виду, что поля в фактической таблице могут быть не равными нулю для полей в классе BaseUser. Поля в классах, связанных с UserType, всегда должны быть нулевыми в базе данных, так как они будут использоваться только определенным типом пользователя.
Изменение: я редактирую пример, чтобы соответствовать настройке, которую я сейчас использую в своем собственном проекте. Эта настройка работает отлично для меня.
BaseUser
поэтому я добавил его. Теперь он жалуется на это:org.hibernate.mapping.SingleTableSubclass cannot be cast to org.hibernate.mapping.RootClass