Как вы видите, у вас есть несовместимое отображение
Вы сказали, что класс установки определяет составной первичный ключ (обратите внимание, что я создал составной класс первичного ключа (SetupId - см. Ниже), который должен реализовывать метод Serializable, equals и hashcode)
package ar.domain;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class Setup implements Serializable {
private SetupId setupId;
private User user;
private Map data= new HashMap();
public SetupId getSetupId() {
return setupId;
}
public void setSetupId(SetupId setupId) {
this.setupId = setupId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Map getData() {
return data;
}
public void setData(Map data) {
this.data = data;
}
public static class SetupId implements Serializable {
private Integer userId;
private String setupItem;
public String getSetupItem() {
return setupItem;
}
public void setSetupItem(String setupItem) {
this.setupItem = setupItem;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (!(o instanceof SetupId))
return false;
final SetupId other = (SetupId) o;
if (!(getUserId().equals(other.getUserId())))
return false;
if (!(getSetupItem().equals(other.getSetupItem())))
return false;
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 11 * hash + (getUserId() != null ? getUserId().hashCode() : 0);
hash = 11 * hash + (getSetupItem() != null ? getSetupItem().hashCode() : 0);
return hash;
}
}
}
Поскольку у вашего класса Setup есть Map of value Type, вы должны определить его составной внешний ключ при определении его отношения (см. Ключевой элемент)
<class name="ar.domain.Setup">
<composite-id name="setupId" class="ar.domain.Setup$SetupId">
<key-property name="setupItem" type="string" column="SETUP_ITEM"/>
<key-property name="userId" type="integer" column="USER_ID"/>
</composite-id>
<many-to-one name="user" class="ar.domain.User" column="USER_ID" insert="false" update="false"/>
<map name="data" table="DATA_TABLE">
<key>
<column name="SETUP_ITEM"/>
<column name="USER_ID"/>
</key>
<map-key column="USER_ID"/>
<element column="SETUP_VALUE" not-null="true" type="string"/>
</map>
</class>
И, в то же время, используйте составной столбец внешнего ключа в качестве ключа карты (USER_ID, верно?), Что не имеет смысла. Почему?
- Hibernate не позволяет обновить столбец (составного) первичного ключа
Кроме того, Hibernate не поддерживает автоматическую генерацию составного первичного ключа
Предположим, здесь идет таблица настроек
SETUP_ITEM USER_ID
0 1
0 2
И ваши DATA_TABLE
SETUP_ITEM USER_ID
0 1
Что произойдет, если вы попробуете следующий
Integer userId = 3;
String setupValue = "someValue";
setup.getData().put(userId, setupValue);
Поскольку таблица SETUP не определяет USER_ID со значением 3, вы увидите нарушение ограничения .
Имейте это в виду
Когда у вас есть (составной) первичный ключ, который нельзя обновить, избегайте его использования, чтобы изменить изменяемое свойство, которое зависит от него . В противном случае Hibernate будет жаловаться на это.