Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 复合实体的更新失败_Java_Hibernate - Fatal编程技术网

Java 复合实体的更新失败

Java 复合实体的更新失败,java,hibernate,Java,Hibernate,我有一个人实体,它与位置实体构成 @ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @Cascade( {org.hibernate.annotations.CascadeType.SAVE_UPDATE }) public Location getLocation() { return location; } 位置实体的名称为Id @Id public S

我有一个人实体,它与位置实体构成

@ManyToOne(fetch = FetchType.EAGER, cascade =
{ CascadeType.PERSIST, CascadeType.MERGE })
@Cascade(
{org.hibernate.annotations.CascadeType.SAVE_UPDATE })
public Location getLocation()
{
    return location;
}
位置实体的名称为Id

@Id
public String getName()
{
    return name;
}
在SpringMVC表单中,当Person的位置从L1更改为L2时,我遇到以下异常,其中Person实体是表单的modelAttribute

org.springframework.orm.hibernate3.HibernateSystemException:com.x.y.z.Location实例的标识符从L2更改为L1;嵌套异常是org.hibernate.HibernateException:com.x.y.z.Location实例的标识符从L2更改为L1

你把我搞糊涂了

您映射的是一个关联;Hibernate(JPA)中的合成通过
@Embedded
/
@Embedded
注释进行映射。关联是独立实体之间的关系;它们通常通过实体标识符(数据库中的外键)连接

在您的特定情况下,
Person
实体指向
Location
实体,这意味着在数据库
PERSONS
表中有一个
Location\u ID
外键(名称可能不同)指向
LOCATIONS
表。您试图做的是更新
位置
端上的键,这是非法的,因为它会切断Hibernate的关系(另一端仍然在内部保留以前的键值)

主键通常应该是代理键,并且一开始就不可更新;如果您确实需要“更新”它,您必须将
位置
人员
解除关联,更新
位置
并再次将其分配给
人员
,或者创建一个全新的
位置
实例并将其分配给您的
人员

综上所述,如果您真的试图对组合关系建模,您需要将@ManyToOne替换为@Embedded,并相应地更改您的表模式。这里有一个链接到 Hibernate注释文档


另外,在两个单独的注释(JPA和Hibernate扩展)中指定级联类型也不是一件好事。如果您真的需要Hibernate扩展(在本例中不需要),只需使用它,并将JPA注释中的
cascade
属性保留为空。

我在独立应用程序中也做了同样的事情。这东西行得通。我认为@modeldattribute应该有问题

在您的位置中,模型类中的实体属性id类型已更改。请参阅id和映射属性id类型相同。请确保id属性getter和setter函数返回类型。