2013-09-26 3 views
2

Последние 4 часа я отчаянно пытаюсь выполнить следующую картографическую работу.Hibernate не удается отобразить картографическую карту с помощью ManyToMany

@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(); 

что я получаю это:
гибернации: (?,) Вставить в Foo (независимо, FOO_ID) значений
Hibernate : вставить в Foo (независимо, FOO_ID) значения (?,?)
Спящий режим: обновить Foo set whatever =? где FOO_ID =?
Hibernate: вставить в FOO_RELATIONSHIP (NESTED_FOO_ID, PARENT_FOO_ID) значения

Это кажется, что спящий режим игнорирует 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; 
} 

Обратите внимание, что это не работает в спящем 3.6.9.Final из следующих Bug

Смежные вопросы