如何创建一个map属性,其中包含键列和map键作为详细信息类的PK的一部分?
像这样:
<class entity-name="Person" >
<id name="id"/>
<property name="birthDate" type="date"/>
<map name="names">
<key column="personId"/>
<map-key type="string" column="code"/>
<one-to-many class="PersonName" />
</map>
</class>
<class entity-name="PersonName">
<composite-id>
<key-many-to-one name="personId" class="Person"/>
<key-property name="code" type="string" length="32"/>
</composite-id>
<property name="lastName" type="string" length="64" index="nameSearch"/>
<property name="firstName" type="string" length="64" index="nameSearch"/>
<property name="middleName" type="string" length="64" index="nameSearch"/>
<property name="isActual" type="boolean"/>
</class>
我需要避免在PersonName类中创建需要特殊处理的代理键。下面显示的Json应该自动保存在数据库中,必要时根据PersonId代码键插入和更新详细记录。
很自然的#34;代码&#34; property将该行与人员ID一起标识。
我尝试了&#34;逆&#34;,&#34; not-null&#34;的不同组合。我承认我没有完全了解它是如何工作的。我收到不同的错误消息,例如:
错误:&#34; person&#34;中的空值列违反NOT NULL约束
详细信息:错误的行包含(null,null,lastname,ffffirst,null,null)。
或:
org.hibernate.MappingException:实体映射中的重复列: PersonName列:person(应使用insert =&#34映射; false&#34; update =&#34; false&#34;)
如果表示为json:
,它应该如下所示{
"birthDate": "33-44-55",
"names": {
"mainName": {
"lastName": "lastname",
"firstName": "ffffirst"
},
"maidenName": {
"lastName": "lastname1",
"firstName": "ffffirst2"
},
"old": {
"lastName": "lastname3",
"firstName": "ffffirst4"
}
}
}
UPD(问题澄清) 实际上这是一个主要目标 - 系统应该在使用此json发布时创建master和所有细节。这个json被转换为映射类。如果主人有一个&#34; id&#34;填充后,系统应更新主数据和详细信息,并在需要时添加新条目。细节(&#34;姓名&#34;地图条目)不应该有任何代理人#id; id&#34;指定。它们由主人&#34; personId&#34;字段和&#34;代码&#34;字段。
**澄清2 ** 如示例json所示,map键是一个字符串,而不是一个复合键。如映射xml所示,这是所有动态映射。不应该写出不能从json自动实例化的其他类。
希望有可能!
为了全面了解,表格生成好了,我喜欢它:
CREATE TABLE personname
(
personid character varying(32) NOT NULL,
code character varying(32) NOT NULL,
lastname character varying(64),
firstname character varying(64),
middlename character varying(64),
isactual boolean,
CONSTRAINT personname_pkey PRIMARY KEY (personid, code),
CONSTRAINT fk_1skg5frawyftx8co9uawhc3r8 FOREIGN KEY (personid)
REFERENCES person (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
答案 0 :(得分:2)
我认为您的映射应如下所示:
对于嵌入式复合id,您需要一个嵌套的Key类(例如Person $ Key,尽管它也可以是外部类):
public static class Key {
private Long personId;
private String code;
public Key(Long personId, String code) {
this.personId = personId;
this.code = code;
}
public Long getPersonId() {
return personId;
}
public String getCode() {
return code;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Key)) {
return false;
}
Key k = (Key)obj;
return personId.equals(k.personId) && code.equals(k.code);
}
@Override
public int hashCode() {
return 37*personId.hashCode() + code.hashCode();
}
}
然后你的地图就像:
private Map<Key,PersonName> names = new HashMap<Key,PersonName>();
Hibernate映射:
<class entity-name="Person" >
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="birthDate" type="date"/>
<map name="names" inverse="true">
<composite-map-key class="Person$Key">
<key-property name="personId"/>
<key-property name="code"/>
</composite-map-key>
<one-to-many class="PersonName" />
</map>
</class>
<class entity-name="PersonName">
<composite-id name="id" class="Person">
<key-property name="personId"/>
<key-property name="code"/>
</composite-id>
<many-to-one name="person" class="Person"
insert="false" update="false">
<column name="personId"/>
<column name="code"/>
</many-to-one>
<property name="lastName" type="string" length="64" index="nameSearch"/>
<property name="firstName" type="string" length="64" index="nameSearch"/>
<property name="middleName" type="string" length="64" index="nameSearch"/>
<property name="isActual" type="boolean"/>
</class>
答案 1 :(得分:1)
这是不可能的。使用mongodb或编写自己的ORM。