2017-11-15 1 views
0

ich diese drei Entitäten:@UniqueConstraint mit mehreren Spalten nicht erzwungen bei der Verwendung von bidirektionalen Mapping

@Entity 
class Resource { 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "resource", cascade = CascadeType.ALL, orphanRemoval = true) 
    List<Element> elements; 

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 
    @JoinColumn(name = "resource_id", nullable = false) 
    List<Action> actions; 
} 

@Entity 
@Table(name = "element", uniqueConstraints = @UniqueConstraint(name = "UK_ELEMENT_VALUE_FOR_RESOURCE", columnNames = { "value", "resource_id" })) 
class Element { 

    String value; 

    @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE }) 
    Resource resource; 
} 

@Entity 
@Table(name = "action", uniqueConstraints = @UniqueConstraint(name = "UK_ACTION_VALUE_FOR_RESOURCE", columnNames = { "value", "resource_id" })) 
class Action { 

    String value; 
    // no reference to Resource 
} 

ich diese beiden Tests geschrieben habe:

Wenn ich eine Ressource mit 2 Aktionen mit dem gleichen Wert anhalten , ich bin mit einem PersistenceException mit Hibernate ConstraintViolationException als Ursache begrüßt, die erwartet wird:

assertEquals(ConstraintViolationException.class, 
    assertThrows(PersistenceException.class,() -> { 
     Resource res = newResource("res"); 
     res.setActions(Arrays.asList(new Action("value"), new Action("value"))); 
     dao.create(res); 
    }).getCause().getClass()); 

Wenn beharren ich eine Ressource mit 2 Elemente mit demselben Wert, die Erstellung ist erfolgreich und es wird keine Ausnahme ausgelöst.

assertEquals(ConstraintViolationException.class, 
    assertThrows(PersistenceException.class,() -> { 
     Resource res = newResource("res"); 
     res.setElements(Arrays.asList(new Element("value"), new Element("value"))); 
     dao.create(res); 
    }).getCause().getClass()); 

Wenn ich die bidirektionale Beziehung durch eine unidirektionale ersetzen, funktioniert mein Test. Ich brauche nicht die bidirektionale Beziehung für Action, aber ich brauche es in Element.

Was mache ich da falsch? Ich bin ein bisschen verloren.

+0

Wird der Fremdschlüssel in Element resource_id erstellt oder wird er als etwas anderes generiert? Sie haben es nicht in Ihren Mappings angegeben, also wäre es an den JPA-Standardeinstellungen, die wir nicht anhand dessen bestimmen können, was Sie weggelassen haben. Überprüfen Sie Ihre Protokolle und die Datenbank auf das, was tatsächlich dort generiert wird. Constraints werden in der Datenbank geprüft, nicht in JPA. – Chris

Antwort

0

Ich habe es selbst die bidirektionale Setter arbeiten in Ressourcenklasse durch den Aufruf:

@PrePersist 
void setBidirectionalMappingsOnPersist() { 
    if (elements != null) { 
     elements.forEach(element -> element.setResource(this)); 
    } 
} 

Ich dachte, dass das mappedBy Attribut in der @OneToMany Zugabe würde die Persistenz-Provider die bidirektionale Mapping handhaben.

Verwandte Themen