Hibernate 4 - 什么应该替代弃用的@MapKey来映射一个Map集合,而Key是一个定制的Hibernate UserType [英] Hibernate 4 - What should replace deprecated @MapKey to map a Map collection while Key is a customized Hibernate UserType
问题描述
|用户| UserAttribute |
| ---------- | ------------------- |
|用户ID(PK)| attributeId(PK)|
| firstName | userId |
| lastName |名称|
|其他| locale |
|活动|值|
在原始 hibernate-3.2.2
中, 一对多双向关系正常工作:
@Entity
@Table (name =User)
public class UserHbm {
@Id
@GeneratedValue(generator =id-generator)
@Column(name = userId)
私人长ID;
@Column
private String firstName;
@Column
private String lastName;
@Column
private String other;
@Column
private boolean active = true;
@OneToMany(mappedBy =user,cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@MapKey(columns = {@Column(name =name),@ Column(name =locale)})
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private Map< AttributeKeyHbm,UserAttributeHbm> attributes = null;
//其他方法,getter&设置等...
}
<$
@GeneratedValue($ name)
@Table(name =UserAttribute)
public class UserAttributeHbm {
@Id
@GeneratedValue generator =id-generator)
@Column(name =attributeId)
私人长ID;
@ManyToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE})
@JoinColumn(name =userId)
private UserHbm user;
@Column
私人字符串名称;
@Column
私有语言环境locale = Locale.ENGLISH;
@Column
私有字符串值;
//其他方法...
}
public class AttributeKeyHbm implements UserType {
protected static int [] SQL_TYPES = {Types.VARCHAR,Types.VARCHAR};
私人字符串名称;
私人语言区域设置;
public AttributeKeyHbm(String name,Locale locale){
this.name = name;
this.locale = locale;
}
//其他重写方法,汇编,deepCopy& nullSafeGet等...
}
是什么让 hibernate
从3.2.2迁移到4.3.11作为属性$ c $的关键字,难以假装的UserType
AttributeKeyHbm
c> UserHbm
AttributeKeyHbm
是一个服装的用户类型的Hibernate,包含 UserAttributeHbm
,名称
和本地
由于hibernate注释 @MapKey
是不推荐使用,我试着逐个使用下面的注释来替换原来的 @MapKey
:
@MapKeyType(value = @ Type(type = com.xxx.xxx.AttributeKeyHbm))
@MapKeyJoinColumns(value = {@MapKeyJoinColumn(name =name),@MapKeyJoinColumn(name =locale)})
@MapKeyJoinColumn(name = AttributeKeyHbm)
$ c $ org.hibernate.MappingException:集合索引映射的列数错误:com.xxx.xxx.UserHbm.attributes类型:com.xxx.xxx.AttributeKeyHbm
所以我的问题是:
- 如何在
UserHbm
与 hibernate-4.3.11
,假设 AttributeKeyHbm
couldn不会被放弃,因为它已被其他API大量使用。
- 由于
AttributeKeyHbm
有两列,是正确的还是足够执行接口 UserType
而不是 CompositeUserType
在这种情况下MapKeyJoinColumns / MapKeyJoinColumn将被跳过,请参阅JPA文档 https://docs.oracle.com/javaee/6/api/javax/persistence/MapKeyJoinColumn.html 我猜他们用于只有实体。
该异常意味着密钥UserType的列号与密钥列不同。
我找不到@MapKeyColumns,但我试过@MapKeyColumn(name =id),并使AttributeKeyHbm只有id,它的工作原理。
因此,所有的都是找到类似MapKeyColumns的注释。
Considering the following two tables:
| User | UserAttribute |
|---------- |-------------------|
| userId(PK)| attributeId(PK) |
| firstName | userId |
| lastName | name |
| other | locale |
| active | value |
In original hibernate-3.2.2
, the one-to-many bidirectional relationship works fine:
@Entity
@Table(name = "User")
public class UserHbm {
@Id
@GeneratedValue(generator = "id-generator")
@Column(name = "userId")
private long id;
@Column
private String firstName;
@Column
private String lastName;
@Column
private String other;
@Column
private boolean active = true;
@OneToMany (mappedBy = "user", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
@MapKey(columns = { @Column(name = "name"), @Column(name = "locale") })
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private Map<AttributeKeyHbm, UserAttributeHbm> attributes = null;
//other methods, getter & setting, etc...
}
@Entity
@Table(name = "UserAttribute")
public class UserAttributeHbm {
@Id
@GeneratedValue(generator = "id-generator")
@Column(name="attributeId")
private long id;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
@JoinColumn(name="userId")
private UserHbm user;
@Column
private String name;
@Column
private Locale locale = Locale.ENGLISH;
@Column
private String value;
// other methods...
}
public class AttributeKeyHbm implements UserType {
protected static int[] SQL_TYPES = { Types.VARCHAR, Types.VARCHAR };
private String name;
private Locale locale;
public AttributeKeyHbm(String name, Locale locale) {
this.name = name;
this.locale = locale;
}
//other override methods, assemble, deepCopy & nullSafeGet, etc...
}
What makes hibernate
migration from 3.2.2 to 4.3.11 difficult is the costumed UserType AttributeKeyHbm
as a key of attributes
in UserHbm
AttributeKeyHbm
is a costumed UserType of Hibernate, containing two columns from UserAttributeHbm
, name
and local
respectively.
Since hibernate annotation @MapKey
is deprecated, I've tried to use the following annotations one by one, to replace the original @MapKey
:
@MapKeyType(value=@Type(type="com.xxx.xxx.AttributeKeyHbm"))
@MapKeyJoinColumns(value={ @MapKeyJoinColumn(name = "name"), @MapKeyJoinColumn(name = "locale")})
@MapKeyJoinColumn(name = "AttributeKeyHbm")
But it all ends up with this exceptions:
org.hibernate.MappingException: collection index mapping has wrong number of columns: com.xxx.xxx.UserHbm.attributes type: com.xxx.xxx.AttributeKeyHbm
So my questions are:
- How to implement the same function in
UserHbm
with hibernate-4.3.11
, given that AttributeKeyHbm
couldn't be abandoned cause it's already used by other API heavily.
- As
AttributeKeyHbm
has two columns, is it correct or enough to implement interface UserType
instead of CompositeUserType
解决方案 First of all, it should replace MapKeyType(Hibernate) with MapKeyClass(JPA) or just remove it since Hibernate will auto detect.
And MapKeyJoinColumns/MapKeyJoinColumn will be skipped in this case, refer to the JPA document https://docs.oracle.com/javaee/6/api/javax/persistence/MapKeyJoinColumn.html I guess they're used for entity only.
The exception means key UserType's column number is not the same with the key column.
I can't find @MapKeyColumns but I tried @MapKeyColumn(name="id") and make AttributeKeyHbm only has "id" and it works.
So all is to find the MapKeyColumns-like annotation.
这篇关于Hibernate 4 - 什么应该替代弃用的@MapKey来映射一个Map集合,而Key是一个定制的Hibernate UserType的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文