简体   繁体   中英

org.hibernate.TransientObjectException: how to properly define one-to-one relationship?

I keep getting this exception when saving a compound object. Still cannot figre out how to overcome it.. Here is my mapping:

@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

Here is DAO method where I get this exception:

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

Here is my 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);
    }
}

The fragment of defined test data:

   <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>

I feel like I botched when defining Cascading here.. But could you help me to correct it?

I've managed to make it work at the cost of simplifying the model.

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

It actually requieres a separate id field, so I created it. And it statred to work smoothly. Will probably go with it as no other solutions were found.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM