在过去的4个小时里,我一直在拼命尝试进行以下制图工作。
@Entity
public class Foo {
@Basic
private String bar;
@Id
@Column(name = "FOO_ID")
@Type(type = "foo.bar.OracleGuidType")
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
private UUID id;
@ManyToMany(mappedBy = "parentFoos", fetch = FetchType.EAGER)
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
@MapKeyColumn(name = "NESTED_FOO_KEY")
private Map<String, Foo> nestedFoos = new
HashMap<String, Foo>();
@ManyToMany
@JoinTable(
name = "FOO_RELATIONSHIP",
joinColumns = @JoinColumn(name = "NESTED_FOO_ID",
referencedColumnName = "FOO_ID"),
inverseJoinColumns = @JoinColumn(name = "PARENT_FOO_ID",
referencedColumnName = "FOO_ID")
)
private Set<Foo> parentFoos = new HashSet<Foo>();
//getters/setters
}
映射可能很复杂,但这就是要求。
问题在于,当我尝试执行以下操作时
Foo parent = new Foo();
parent.setWhatever("parent");
Foo child = new Foo();
child.setWhatever("child");
Session currentSession = sessionFactory.getCurrentSession();
Transaction tx = currentSession.getTransaction();
tx.begin();
currentSession.saveOrUpdate(child);
tx.commit();
currentSession = sessionFactory.getCurrentSession();
tx = currentSession.getTransaction();
tx.begin();
child.getParentFoos().add(parent);
parent.getNestedFoos().put("ASDF_KEY", child);
currentSession.saveOrUpdate(parent);
tx.commit();
我得到的是:
Hibernate:插入Foo(无论如何,FOO_ID)值(?,?)
Hibernate:插入Foo(无论如何,FOO_ID)值(?,?)
Hibernate:更新Foo设置什么=?其中FOO_ID =?
Hibernate:插入FOO_RELATIONSHIP(NESTED_FOO_ID,PARENT_FOO_ID)值(?,?)
似乎hibernate忽略了mapkeycolumn(虽然它通过hbm2ddl创建了一个),接下来我得到的是这个例外
引起:java.sql.BatchUpdateException:ORA-01400:无法插入NULL(“BAR”。“FOO_RELATIONSHIP”。“NESTED_FOO_KEY”)
我相信,这个实体可以映射。请帮我解决这个问题。
答案 0 :(得分:1)
我设法通过引入中间实体“映射”来解决问题。
这是我设法做的工作。
@Entity
@Table(name = "FOO")
public class Foo {
@Basic
private String bar;
@Id
@Column(name = "FOO_ID")
@Type(type = "foo.bar.OracleGuidType")
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
private UUID id;
@OneToMany(mappedBy = "parentEntity", fetch = FetchType.EAGER,
cascade = CascadeType.ALL)
private Set<Mapping> nestedFoos = new HashSet<>();
@OneToMany(mappedBy = "childEntity", fetch = FetchType.EAGER,
cascade = CascadeType.ALL)
private Set<Mapping> parentFoos = new HashSet<>();
@Transient
private Map<String, Foo> _nestedFoos = new HashMap<>();
@Transient
private Set<Foo> _parentFoos = new HashSet<>();
@PostLoad
@PostUpdate
@PostPersist
private void fillTransientFields() {
_nestedFoos.clear();
_parentFoos.clear();
for (Mapping mapping : nestedFoos) {
_nestedFoos.put(mapping.getMappingKey(), mapping.getChildEntity());
}
for (Mapping mapping : parentFoos) {
_parentFoos.add(mapping.getParentEntity());
}
}
public Map<String, Foo> geNestedFoos() {
return Collections.unmodifiableMap(_nestedFoos);
}
public Set<Foo> getParentFoos() {
return Collections.unmodifiableSet(_parentFoos);
}
public void addParent(String key, Foo parent) {
Mapping mapping = new Mapping();
mapping.setMappingKey(key);
mapping.setChildEntity(this);
mapping.setParentEntity(parent);
parentFoos.add(mapping);
}
public void addChild(String key, Foo child) {
Mapping mapping = new Mapping();
mapping.setMappingKey(key);
mapping.setChildEntity(child);
mapping.setParentEntity(this);
nestedFoos.add(mapping);
}
public void removeChild(String key) {
for (Mapping mapping : nestedFoos) {
if (mapping.getMappingKey().equals(key)) {
nestedFoos.remove(mapping);
}
}
}
}
@Entity
@Table(name = "FOO_MAPPING_TABLE",
uniqueConstraints = {@UniqueConstraint(columnNames =
{"MAPPING_KEY", "PARENT_ENTITY_ID"})})
class Mapping {
@Basic
@Column(name = "MAPPING_KEY")
private String mappingKey;
@Id
@GenericGenerator(name = "generator", strategy = "increment")
@GeneratedValue(generator = "generator")
@Column(name = "ID")
private Long id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "PARENT_ENTITY_ID", nullable = false, updatable = false)
private Foo parentEntity;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CHILD_ENTITY_ID", nullable = false, updatable = false)
private Foo childEntity;
}
注意,由于以下Bug
,这在Hibernate 3.6.9.Final中不起作用