Как вы сопоставляете карту в спящем режиме с помощью аннотаций?

Используя аннотации, как вы сопоставляете поле в сущности, которая является «картой» (хэш-таблицей) строки, с заданным объектом? Объект аннотирован, и его экземпляры уже хранятся в базе данных гибернации.

Я нашел синтаксис для определения карты с помощью простого ключа и значения как такового:

<class name="Foo" table="foo">
    ...
    <map role="ages">
         <key column="id"/>
         <index column="name" type="string"/>
         <element column="age" type="string"/>
     </map>
 </class>

И как ни странно, с сущностью в качестве ключа и простым типом в качестве значения:

<class name="Foo" table="foo">
    ...
  <map role="ages">
    <key column="id"/>
    <index-many-to-many column="person_id" 
         class="Person"/>
    <element column="age" type="string"/>
  </map>
</class>
<class name="Person" table="person">
    ...
    <property name="name" column="name" 
         type="string"/>
</class>

Но я не понимаю, как это сделать для простого сопоставления ключа с элементом, и я не понимаю, как это сделать с помощью аннотаций.


person Omar Kooheji    schedule 24.02.2010    source источник
comment
Это правильно объяснено здесь /3393649/   -  person jalogar    schedule 24.01.2012


Ответы (4)


Вы можете просто использовать аннотацию JPA @MapKey (обратите внимание, что аннотация JPA отличается от аннотации Hibernate, Hibernate @MapKey сопоставляет столбец базы данных, содержащий ключ карты, а аннотация JPA сопоставляет свойство, которое будет использоваться в качестве ключа карты. ).

@javax.persistence.OneToMany(cascade = CascadeType.ALL)
@javax.persistence.MapKey(name = "name")
private Map<String, Person> nameToPerson = new HashMap<String, Person>();
person Pascal Thivent    schedule 25.02.2010
comment
Спасибо, я попробую это. Какую схему базы данных это отражает? Я использую блок БД и хочу иметь возможность заполнять набор данных с помощью XML. Использует ли это таблицу соединений? если да, то можете ли вы указать, как называется таблица и каковы столбцы таблицы соединений? - person Omar Kooheji; 25.02.2010
comment
@Omar Создает таблицу соединений (по умолчанию FOO_PERSON). Вы можете управлять именем, используя @javax.persistence.JoinTable. Насчет колонок не уверен. - person Pascal Thivent; 25.02.2010

Я знаю, что этот вопрос очень старый, но, возможно, это может кому-то помочь.

Другая возможность примерно такая:

@Entity
@Table(name = "PREFERENCE", uniqueConstraints = { @UniqueConstraint(columnNames = { "ID_DOMAIN", "ID_USER", "KEY" })})
public class Preferences {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID", unique = true, nullable = false)
    private Long id;

    @Column(name = "ID_DOMAIN", unique = false, nullable = false")
    private Long domainId;

    @Column (name = "PREFERENCE_KEY")
    @Enumerated(EnumType.STRING)
    private PreferenceKey key;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_USER", referencedColumnName = "ID")
    private User user;
}

and 

@Entity
@Table(name = "USER", uniqueConstraints = { @UniqueConstraint(columnNames = { "ID_DOMAIN", "LOGIN" })})
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID", unique = true, nullable = false)
    private Long id;

    @Column(name = "ID_DOMAIN", unique = false, nullable = false")
    private Long domainId;

    // more fields

    @ElementCollection(fetch = FetchType.LAZY)
    @JoinColumns({@JoinColumn(name = "ID_USER", referencedColumnName = "ID"), @JoinColumn(name = "ID_DOMAIN", referencedColumnName = "ID_DOMAIN")})
    @OneToMany(targetEntity = Preferences.class, fetch = FetchType.LAZY)
    @MapKey(name = "key")
    private Map<PreferenceKey, Preferences> preferencesMap;
}

Это создает только две таблицы User и Preferences, обратите внимание, что PreferenceKey уникален для пользователя в домене.

person Juan    schedule 25.01.2016

Вероятно, вам следует использовать UserType или UserCollectionType. Или вы можете использовать собственный tupleizer.

см. основную документацию по спящему режиму для ознакомления с концепциями и документация по аннотациям гибернации для эквивалентного подхода к аннотациям.

Дайте мне знать, если это не то, о чем вы просите.

person Jeff Walker    schedule 24.02.2010
comment
Ненавижу показаться идиотом, но я просматривал те же самые две страницы весь день и, кажется, не понял. Я смотрел на этот стиль: ‹роль карты=возраст› ‹ключевой столбец=id/› ‹столбец индекса=тип имени=строка/› ‹столбец элемента=возраст тип=строка/› ‹/карта› Который кажется то, что мне нужно, я просто не понимаю, как это сделать как аннотацию. Я также не знаю, как бы я это сделал, если бы элемент не был строкой. У меня не тот конец палки. - person Omar Kooheji; 24.02.2010
comment
Да, я думаю, вам действительно нужен UserType, потому что все остальные вещи, обсуждаемые здесь (я полагаю), создают еще одну таблицу для хранения карты. Посмотрите на интерфейс UserType, и вы увидите, что есть только несколько методов для реализации. По сути, вы сообщаете hibernate, учитывая ResultSet, как поместить его в тип java и наоборот. - person Jeff Walker; 25.02.2010

person    schedule
comment
Это то, что я ищу, но как бы я это сделал, если бы ключ был строкой, как в примере, а значением был другой объект? - person Omar Kooheji; 25.02.2010
comment
Это похоже на аннотацию для отображения Enum. - person James P.; 25.02.2010
comment
@Omar: Должно быть так же просто, как заменить String типом объекта по вашему выбору. Возможно, вам придется удалить @Column(name = age) и добавить что-то вроде inverseJoinColumns=@JoinColumn(name=fk_ik) в аннотацию @JoinTable. Хотя не уверен. - person whiskeysierra; 25.02.2010
comment
Я пробовал что-то подобное для сохранения ArrayList (столбец с обратным соединением), но столкнулся с некоторыми проблемами с моими тестами DBUnit, они не могли удалить таблицы для их повторного заполнения, потому что между двумя таблицами существовала циклическая зависимость. - person Omar Kooheji; 25.02.2010
comment
Вы пытались сохранить один массив в качестве значения карты? - person whiskeysierra; 25.02.2010