2017-03-20 5 views
1

Ich bekomme diese Ausnahme beim Speichern eines zusammengesetzten Objekts. Immer noch nicht figre kann, wie es zu überwinden .. Hier ist mein Mapping:org.hibernate.TransientObjectException: Wie definiert man eine Eins-zu-Eins-Beziehung?

@Entity 
@Table(name = "store_house") 
public class StoreHouse implements Serializable { 

    // constructors 

    @Id 
    @OneToOne(fetch = FetchType.EAGER) 
    @Cascade({org.hibernate.annotations.CascadeType.ALL}) 
    @JoinColumn(name="ING_ID", unique=true, nullable=false, updatable=false) 
    private Ingredient ingredient; 

    @Column(name = "QUANTITY") 
    private double quantity; 
} 

// getters and setters 

Hier ist DAO-Methode, wo ich diese Ausnahme erhalten:

@Override 
    public void insert(StoreHouse sh) { 
     sessionFactory.getCurrentSession().persist(sh); 
    } 

Hier ist mein Test calss:

@Transactional 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"/test-context.xml", "/test-data.xml"}) 
public class StoreHouseDAOTest { 

    @Autowired 
    private SessionFactory sessionFactory; 

    @Autowired 
    private StoreHouseDAO storeHouseDAO; 

    @Autowired 
    private StoreHouse expectedStoreHouse; 

    @Test 
    public void itShouldPerformCRUDSmoothly() { 
      // CREATE 
      storeHouseDAO.insert(expectedStoreHouse); 
      sessionFactory.getCurrentSession().flush(); 
      // READ 
      StoreHouse actualStoreHouse = storeHouseDAO.getByIngredient(expectedStoreHouse.getIngredient()); 
      assertEquals(actualStoreHouse.getIngredient().getId(), expectedStoreHouse.getIngredient().getId()); 
      // DELETE 
      storeHouseDAO.delete(expectedStoreHouse); 
      sessionFactory.getCurrentSession().flush(); 
      StoreHouse emptyStoreHouse = storeHouseDAO.getByIngredient(expectedStoreHouse.getIngredient()); 
      assertNull(emptyStoreHouse); 
    } 
} 

Das Fragment der definierten Testdaten:

<bean id="expectedIngredient" class="com.restaurant.model.Ingredient"> 
     <property name="name" value="TestIngredient"/> 
     <property name="unit" value="expectedUnit"/> 
    </bean> 

    <bean id="expectedStoreHouse" class="com.restaurant.model.StoreHouse"> 
     <property name="ingredient" ref="expectedIngredient"/> 
     <property name="quantity" value="10"/> 
    </bean> 

Ich fühle mich wie ich verpfuscht, wenn Cascading hier definiert .. Aber könnten Sie mir helfen, es zu korrigieren?

+0

Wie Sie @Cascade ({org.hibernate.annotations.CascadeType.ALL}) definiert haben, wird Ihr erwarteterIngredient zusammen mit expectedStoreHouse gelöscht. Sie können also expectedStoreHouse.getIngredient() nach dem Entfernen von StoreHouse nicht aufrufen. Sie sollten den Löschkaskadentyp ausschließen oder den Komponententest ändern. – xl0e

+0

Danke für die Antwort! Ich kommentierte den Abschnitt Delete im Test und bekam das gleiche Problem ((. Logs zeigen, dass die Insert-Methode fehlschlägt und an keiner Stelle Ingredient einfügt: Objekt referenziert eine nicht gespeicherte transiente Instanz - speichert die vorübergehende Instanz vor derQuery-Flushing: com.restaurant .model.Ingredient. Das Problem verbirgt sich anderswo, vielleicht in Cascade maping, es funktioniert einfach nicht wie erwartet ... –

Antwort

0

Ich habe es geschafft, es auf Kosten der Vereinfachung des Modells arbeiten zu lassen.

@Entity 
@Table(name = "store_house") 
public class StoreHouse implements Serializable { 

    // constructors 

    @Id 
    @GeneratedValue(generator = "increment") 
    @GenericGenerator(name = "increment", strategy = "increment") 
    @Column(name = "SH_ID") 
    private Long id; 

    @OneToOne(fetch = FetchType.EAGER) 
    @Cascade({org.hibernate.annotations.CascadeType.ALL}) 
    @JoinColumn(name="ING_ID", unique=true, nullable=false, updatable=false) 
    private Ingredient ingredient; 

    @Column(name = "QUANTITY") 
    private double quantity; 

    // getters and setters 
    } 

Es erfordert tatsächlich ein separates ID-Feld, also habe ich es erstellt. Und es hat sich bewährt, um reibungslos zu funktionieren. Wird wahrscheinlich damit gehen, da keine anderen Lösungen gefunden wurden.

Verwandte Themen