gpt4 book ai didi

java - Hibernate 无法使用 ManyToMany 映射 Map 集合

转载 作者:行者123 更新时间:2023-11-30 11:28:05 24 4
gpt4 key购买 nike

在过去的 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 set whatever=?其中 FOO_ID=?
hibernate :插入 FOO_RELATIONSHIP (NESTED_FOO_ID, PARENT_FOO_ID) 值 (?, ?)

hibernate 似乎忽略了 mapkeycolumn(尽管它通过 hbm2ddl 创建了一个),接下来我得到的是这个异常

Caused by: java.sql.BatchUpdateException: ORA-01400: Unable to insert NULL into ("BAR"."FOO_RELATIONSHIP"."NESTED_FOO_KEY")

我相信,这个实体是可以映射的。请帮我解决这个问题。

最佳答案

我设法通过引入一个中间实体“映射”来解决这个问题。

这是我设法完成的工作。

@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;
}

请注意,这在 Hibernate 3.6.9.Final 中不起作用,因为以下 Bug

关于java - Hibernate 无法使用 ManyToMany 映射 Map 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19023217/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com