Java 使用区域设置作为键的地图的Hibernate注释
我有这些桌子:Java 使用区域设置作为键的地图的Hibernate注释,java,hibernate,annotations,Java,Hibernate,Annotations,我有这些桌子: CREATE TABLE PRODUCT ( ID NUMBER(19,0) NOT NULL, CONSTRAINT PRODUCT_PK PRIMARY KEY (ID) USING INDEX ( CREATE UNIQUE INDEX PRODUCT_PK ON PRODUCT(ID) ... ) ) ... CREATE TABLE PRODUCT_LOCALE ( PRODUCT_ID NUMBER(19,0) NOT
CREATE TABLE PRODUCT (
ID NUMBER(19,0) NOT NULL,
CONSTRAINT PRODUCT_PK
PRIMARY KEY (ID)
USING INDEX (
CREATE UNIQUE INDEX PRODUCT_PK
ON PRODUCT(ID)
...
)
)
...
CREATE TABLE PRODUCT_LOCALE (
PRODUCT_ID NUMBER(19,0) NOT NULL,
LOCALE VARCHAR2(12 CHAR) NOT NULL,
NAME VARCHAR2(160 CHAR),
CONSTRAINT PRODUCT_LOCALE_PK
PRIMARY KEY (PRODUCT_ID,LOCALE)
)
...
由该类代表:
public class Product extends LocalizedEntity<Product.LocalizedFields> {
....
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public static class LocalizedFields implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
公共类产品扩展了本地化特性{
....
私人长id;
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共静态类LocalizedFields实现可序列化{
私有字符串名称;
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
}
}
还有它的超级级
public abstract class LocalizedEntity<T> implements serializable {
....
private Map<Locale, T> localizedFields = new HashMap<Locale, LF>();
public Map<Locale, T> getLocalizedFields() {
return localizedFields;
}
public void setLocalizedFields(Map<Locale, T> localizedFields) {
this.localizedFields = localizedFields;
}
}
public抽象类LocalizedEntity实现可序列化{
....
private Map localizedFields=新HashMap();
公共地图getLocalizedFields(){
返回本地化字段;
}
public void setLocalizedFields(映射localizedFields){
this.localizedFields=localizedFields;
}
}
我将Hibernate与.hbm.xml文件一起使用,该标记正在工作:
.....
<map name="localizedFields" table="product_locale" lazy="false" fetch="select" batch-size="100">
<cache usage="read-write" />
<key column="product_id" not-null="true" />
<map-key type="locale">
<column name="locale" length="12" not-null="true" />
</map-key>
<composite-element class="com.myproject.Product$LocalizedFields">
<property name="name" type="string">
<column name="name" length="500" />
</property>
</composite-element>
</map>
.....
。。。。。
.....
现在我必须使用注释,因此我迁移到以下位置:
@Entity
@Table(name = "product")
public class Product extends LocalizedEntity<Product.LocalizedFields> {
....
private Long id;
@Id
@Column(name = "id")
@GeneratedValue(strategy= GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ElementCollection(fetch = FetchType.EAGER)
@JoinTable(name = "product_locale", joinColumns = @JoinColumn(name = "product_id", nullable = false))
@MapKeyClass(value = Locale.class)
@MapKeyColumn(name = "locale", length = 12, nullable = false)
@BatchSize(size = 100)
@Fetch(FetchMode.SELECT)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Embedded
public Map<Locale, LocalizedFields> getLocalizedFields() {
return super.getLocalizedFields();
}
@Embeddable
public static class LocalizedFields implements Serializable {
....
private String name;
@Column(name = "name", length = 500, nullable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
@实体
@表(name=“产品”)
公共类产品扩展了地方性{
....
私人长id;
@身份证
@列(name=“id”)
@GeneratedValue(策略=GenerationType.AUTO)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
@ElementCollection(fetch=FetchType.EAGER)
@JoinTable(name=“product\u locale”,joinColumns=@JoinColumn(name=“product\u id”,nullable=false))
@MapKeyClass(值=Locale.class)
@MapKeyColumn(name=“locale”,length=12,nullable=false)
@批量大小(大小=100)
@Fetch(FetchMode.SELECT)
@缓存(用法=CacheConcurrencyStrategy.READ\u WRITE)
@嵌入
公共地图getLocalizedFields(){
返回super.getLocalizedFields();
}
@可嵌入
公共静态类LocalizedFields实现可序列化{
....
私有字符串名称;
@列(name=“name”,长度=500,可空=false)
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
}
}
而且
@MappedSuperclass
public abstract class LocalizedEntity<T> implements serializable {
....
private Map<Locale, T> localizedFields = new HashMap<Locale, LF>();
public Map<Locale, T> getLocalizedFields() {
return localizedFields;
}
public void setLocalizedFields(Map<Locale, T> localizedFields) {
this.localizedFields = localizedFields;
}
}
@MappedSuperclass
公共抽象类LocalizedEntity实现了可序列化{
....
private Map localizedFields=新HashMap();
公共地图getLocalizedFields(){
返回本地化字段;
}
public void setLocalizedFields(映射localizedFields){
this.localizedFields=localizedFields;
}
}
它抛出了这个错误:
原因:org.hibernate.MappingException:无法确定列:[org.hibernate.mapping.Column(localizedFields)]的表:product中的java.util.Map的类型
位于org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:349)
位于org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:322)
位于org.hibernate.mapping.Property.isValid(Property.java:241)
位于org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:496)
位于org.hibernate.mapping.RootClass.validate(RootClass.java:270)
位于org.hibernate.cfg.Configuration.validate(Configuration.java:1360)
位于org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1851)
位于org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
位于org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
位于org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454)
位于org.springframework.orm.hibernate4.LocalSessionFactoryBean.AfterPropertieSet(LocalSessionFactoryBean.java:439)
位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
... 103更多
如果我将@MapKeyClass(value=Locale.class)和@MapKeyColumn替换为@MapKey(“Locale”),则会引发以下错误:
原因:org.hibernate.AnnotationException:未找到关联类:com.myproject.Product$LocalizedFields
位于org.hibernate.cfg.annotations.MapBinder.bindKeyFromAssociationTable(MapBinder.java:133)
访问org.hibernate.cfg.annotations.MapBinder.access$000(MapBinder.java:76)
位于org.hibernate.cfg.annotations.MapBinder$1.secondPass(MapBinder.java:111)
位于org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70)
位于org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1697)
位于org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426)
位于org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
位于org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
位于org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
位于org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454)
位于org.springframework.orm.hibernate4.LocalSessionFactoryBean.AfterPropertieSet(LocalSessionFactoryBean.java:439)
位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
... 103更多
我发现问题在于关键的“区域设置” 根据JPA文档(): “为类型的关联指定映射键的类型 Map键可以是一个基本类型,一个可嵌入类, “或实体” Locale不是基本类型、可嵌入类型或实体,而是Hibernate使用其内部类型“Locale”(它是org.Hibernate.type.Locale的别名)管理的自定义类型
@ElementCollection(fetch = FetchType.EAGER)
@JoinTable(name = "product_locale", joinColumns = @JoinColumn(name = "product_id", nullable = false))
@MapKeyColumn(name = "locale", length = 12, nullable = false)
@MapKeyType(value = @Type(type = "locale"))
@BatchSize(size = 100)
@Fetch(FetchMode.SELECT)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)