Java Hibernate无法使用多个映射映射集合

Java Hibernate无法使用多个映射映射集合,java,hibernate,Java,Hibernate,在过去的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 = "s

在过去的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

}
我得到的是:
Hibernate:将值(?,)插入到Foo(无论什么,Foo_ID)中
Hibernate:将值(?,)插入到Foo(无论什么,Foo_ID)中
Hibernate:更新Foo set whatever=?其中FOO_ID=?
Hibernate:插入到FOO_关系(嵌套的FOO_ID、父FOO_ID)值(?,)

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

原因:java.sql.BatchUpdateException:ORA-01400:无法将NULL插入(“BAR”“FOO\u关系”“嵌套的\u FOO\u键”)


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

我通过引入中间实体“映射”解决了此问题

以下是我设法使之发挥作用的内容

@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;
}
@实体
@表(name=“FOO”)
公开课Foo{
@基本的
私人弦杆;
@身份证
@列(name=“FOO\u ID”)
@类型(Type=“foo.bar.OracleGuidType”)
@GeneratedValue(generator=“系统uuid”)
@GenericGenerator(name=“system uuid”,strategy=“uuid2”)
私有UUID;
@OneToMany(mappedBy=“parentEntity”,fetch=FetchType.EAGER,
级联=级联类型(全部)
私有集nestedFoos=newhashset();
@OneToMany(mappedBy=“childEntity”,fetch=FetchType.EAGER,
级联=级联类型(全部)
private Set parentFoos=new HashSet();
@短暂的
私有映射_nestedFoos=newhashmap();
@短暂的
私有集_parentFoos=new HashSet();
@后装
@假想
@后复印机
私有void fillTransientFields(){
_nestedFoos.clear();
_parentFoos.clear();
for(映射:nestedFoos){
_nestedFoos.put(mapping.getMappingKey(),mapping.getChildEntity());
}
for(映射:parentFoos){
_add(mapping.getParentEntity());
}
}
公共地图geNestedFoos(){
返回集合。不可修改映射(_nestedFoos);
}
公共集getParentFoos(){
返回集合。不可修改集(\u parentFoos);
}
public void addParent(字符串键,Foo parent){
映射映射=新映射();
mapping.setMappingKey(key);
mapping.setChildEntity(this);
mapping.setParentEntity(父级);
parentFoos.add(映射);
}
public void addChild(字符串键,Foo child){
映射映射=新映射();
mapping.setMappingKey(key);
mapping.setChildEntity(child);
mapping.setParentEntity(this);
添加(映射);
}
public void removeChild(字符串键){
for(映射:nestedFoos){
if(mapping.getMappingKey().equals(key)){
nestedFoos.remove(映射);
}
}
}
}
@实体
@表(name=“FOO\u映射表”,
uniqueConstraints={@UniqueConstraint(列名称=
{“映射\u键”、“父\u实体\u ID”})
类映射{
@基本的
@列(name=“MAPPING\u KEY”)
私有字符串映射密钥;
@身份证
@GenericGenerator(name=“generator”,strategy=“increment”)
@GeneratedValue(generator=“generator”)
@列(name=“ID”)
私人长id;
@manytone(fetch=FetchType.EAGER)
@JoinColumn(name=“PARENT\u ENTITY\u ID”,nullable=false,updateable=false)
私人富母公司;
@manytone(fetch=FetchType.EAGER)
@JoinColumn(name=“CHILD\u ENTITY\u ID”,nullable=false,updateable=false)
私营富国儿童实体;
}

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

请发布表格结构。
@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;
}