我是Hibernate的新手,我正在努力学习JPA和Hibernate。
我想知道Hibernate不允许保存引用未保存的瞬态实例的对象的原因是什么?我想知道为什么这是一个问题?
我问了一个人,他们中的一些人这样回答我:
如果数据库中还没有地址记录,我们怎么可能将客户映射到地址?
和
您正在为客户分配特定地址。但地址没有任何ID
但老实说,我不理解他们。
(我知道会抛出异常,解决方案是级联,但我想在数据库中说明问题的原因)
现在,假设我们有所有这些代码:
(我以双向一对一关系为例)
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
@OneToOne(mappedBy = "customer")
private Address address;
}
--
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String street;
private String zipCode;
@OneToOne
private Customer customer;
}
--
public static void main(String[] args) {
EntityManager entityManager = emf.createEntityManager();
entityManager.getTransaction().begin(); // Begin Transaction
Customer c1 = new Customer("Mi", "S");
Address addrss1 = new Address("5412 S 5th", "212524");
c1.setAddress(addrss1);
addrss1.setCustomer(c1);
entityManager.persist(c1);
entityManager.getTransaction().commit(); // Commit
entityManager.close();
}
让我们假设没有抛出异常,并且java和hibernate允许我们运行我们的代码,这是我们的客户表。
id firstName lastName
---------------------------------
1 Mi S
现在,问题是什么?这种双向一对一关系中的一切似乎都是正确的。那问题是什么?
客户是新的,从你想要插入它的持久调用中可以清楚地看出,但是不清楚你想要对任何客户的引用发生什么。为了清楚起见,你定义了你希望JPA提供者(Hibernate)在任何/所有情况下在映射中做什么-这就是级联操作所指的。在这种情况下,JPA将查看customer.addressOneToOne映射,发现没有任何定义;Address不在这个EntityManager上下文中进行管理,因此它不知道如何处理这种关系,因此它通过抛出错误来表明你犯了错误。
如果它让它通过,您的客户实例引用了不存在的东西,并且它的状态与数据库中的内容不匹配。您传递给持久化的应该是您在读取时会返回的内容,因此它应该反映数据库中的状态。请记住,JPA在实体身份方面非常重要,因为这允许在多级缓存中缓存这些实体,并且该实体可能会按原样进入这些缓存。它必须知道如何处理对不存在的实体的引用,并且规范决定要求例外。
问题并不直接与您的持久化调用有关,因为规范确实允许提供者忽略对没有级联设置的分离/新实例的引用——发生的事情只是未定义。在这种情况下,您出错的地方是刷新/提交,即持久化单元同步到数据库(JPA 3.0的第3.2.4节),这要求提供者通过托管实体,然后确定任何更改。在持久化之前添加新地址将导致与在持久化之后添加相同的问题,并且要求提供者在发现新的或删除的实体并回滚事务时抛出IllegalStateException。
错误: 我还尝试了,但是 病因是什么?显然,我设置了nullable=true(在数据库中也是如此),尽管我有这个错误。有什么想法吗?
我有一个数据库,有两个表Batchstatistics和ReconProcessDateTracker。我想了解他们之间的关系。我使用以下模型类使用hibernate实现这一点: } } 当我试图保存它时,我得到的错误对象引用了一个未保存的瞬态实例——在刷新之前保存瞬态实例:com。美国药典。实体TBLBatch统计
受雇的 Emploadable
我正在使用Seam Framework。我有2个实体: Request.java 和请求事件.java 当我进行此交易时: 我得到了这个错误:
我有两个例子。一个是项目,一个是模块。< code >一对多关系。 我将模块设置到项目中。然后使用。第一次,因为数据库中没有记录,所以项目和模块可以保存到数据库中。然而,第二次,因为我不需要创建新项目,我只创建新模块,然后将模块设置回项目。 发生异常。 对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例。 有什么办法可以解决这个问题吗谢谢
上图显示了表之间的关系。 AddressType表包含静态值,如mailing、home、work等。 在AddressTypeRel模型类中,我有一个带有多对一注释的AddressType对象