【问题标题】:org.hibernate.TransientObjectException: how to properly define one-to-one relationship?org.hibernate.TransientObjectException:如何正确定义一对一关系?
【发布时间】:2017-03-20 10:28:48
【问题描述】:

保存复合对象时,我不断收到此异常。仍然无法弄清楚如何克服它.. 这是我的映射:

@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

这是我得到此异常的 DAO 方法:

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

这是我的测试课:

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

定义的测试数据片段:

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

我觉得在这里定义级联时我搞砸了。但是你能帮我纠正一下吗?

【问题讨论】:

  • 正如你定义的@Cascade({org.hibernate.annotations.CascadeType.ALL}) 你的expectedIngredient 将与expectedStoreHouse 一起被删除。所以你不能在删除 StoreHouse 后调用 expectedStoreHouse.getIngredient()。您应该排除删除级联类型,或更改单元测试。
  • 感谢您的回答!我在测试中评论了删除部分并得到了同样的问题((。日志显示插入方法失败并且实际上并没有首先插入成分:对象引用了未保存的瞬态实例 - 在查询刷新之前保存瞬态实例:com.restaurant .model.Ingredient。所以问题隐藏在其他地方,也许在级联映射中,它根本无法按预期工作......

标签: java spring hibernate one-to-one cascading


【解决方案1】:

我已经设法以简化模型为代价使其发挥作用。

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

它实际上需要一个单独的 id 字段,所以我创建了它。它运行顺利。由于没有找到其他解决方案,因此可能会采用它。

【讨论】:

    猜你喜欢
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 2011-04-10
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多