Java 在合并对象后更改对象(持久性上下文)会中断更新

Java 在合并对象后更改对象(持久性上下文)会中断更新,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我需要进行两次连续的手术。 首先,我插入一条新记录(我使用JPA)作为历史记录使用,然后我对一条记录运行更新,该记录总是作为最“最新”的记录使用,并在通话中收到信息 问题是对象有一个复合键,我需要插入它,但我不希望它在更新后返回的JSON中返回。JPA在更改组合键方面确实存在问题,但我发现了.detach方法,该方法在过去对我有效。我希望为null的字段在实际对象中被标记为@Transient,并且不会抛出任何错误。它可以很好地执行插入操作,但是如果我尝试移动主键,更新就会失败。甚至在调用ins

我需要进行两次连续的手术。 首先,我插入一条新记录(我使用JPA)作为历史记录使用,然后我对一条记录运行更新,该记录总是作为最“最新”的记录使用,并在通话中收到信息

问题是对象有一个复合键,我需要插入它,但我不希望它在更新后返回的JSON中返回。JPA在更改组合键方面确实存在问题,但我发现了.detach方法,该方法在过去对我有效。我希望为null的字段在实际对象中被标记为@Transient,并且不会抛出任何错误。它可以很好地执行插入操作,但是如果我尝试移动主键,更新就会失败。甚至在调用insert之后,甚至使用.detach方法。你知道我错过了什么吗

我想我可以这样做:

          em.merge(contract); //Object to be saved
          em.detach(contract); // allows me to manipulate it

          policy.setContractNum(policy.getId().getContractNum());
          policy.setCustNum(policy.getId().getCustNum());

          returnPolicyAsList.add(policy);

          customer.setPolicies(returnPolicyAsList);
          status.setFamCustomer(customer);
          status.setStatus(Message.SUCCESS);
          status.setStatusMessage(Message.SUCCESS);

          return status;

你似乎不太符合JPA的世界模式。实体的主键是其标识。因此

这与Java的视图有点冲突,Java的视图为每个对象赋予一个单独的标识。您可以使用Java视图处理非持久性的实体,即新的、分离的或删除的实体。这就是为什么你可以在分离一个实体的PK后旋转它,但是你必须明白,从JPA的角度来看,这样做会改变它的身份。如果您以后尝试合并这样一个实体,那么JPA只会看到它的新身份,而不会看到它的旧身份


如果您需要更改实体的主键(通常是一个坏主意),那么您应该删除它,更改主键,然后再次保留它。另一方面,如果你的主键包含的信息可能会随着时间的推移而改变,那么你真的应该选择不同的主键。事实上,当您使用代理PK而不是包含业务数据的PK时,JPA工作得最顺利。

您似乎不太符合JPA的世界模型。实体的主键是其标识。因此

这与Java的视图有点冲突,Java的视图为每个对象赋予一个单独的标识。您可以使用Java视图处理非持久性的实体,即新的、分离的或删除的实体。这就是为什么你可以在分离一个实体的PK后旋转它,但是你必须明白,从JPA的角度来看,这样做会改变它的身份。如果您以后尝试合并这样一个实体,那么JPA只会看到它的新身份,而不会看到它的旧身份


如果您需要更改实体的主键(通常是一个坏主意),那么您应该删除它,更改主键,然后再次保留它。另一方面,如果你的主键包含的信息可能会随着时间的推移而改变,那么你真的应该选择不同的主键。实际上,当您使用代理PK而不是包含业务数据的PK时,JPA工作得最顺利。

detach
用于跨会话操作。不要使用
detach
仅仅是为了能够以Hibernate不期望的方式操作对象。Hibernate没想到会这样!另外,您的代码在
分离
之后的任何地方都不使用
合同
,因此我不知道您想做什么。对不起,我可能已经说得更清楚了。我马上就要编辑了。我有一个用于插入的嵌入式id,但我不希望它们以实际的JSON返回。所以我有两个同名的临时字段,我只是移动它们——但是在我更新之后。我不希望在JSON中返回密钥,这本质上是我的目标。我会发布更多的代码示例,让您有更好的想法。您需要提供更多的代码。您有一个引用实体的契约变量,但我看不到该变量的其他用途。您确定要使用合并吗?我从不使用我的实体来生成JSON,但为此我有一组单独的DTO类,这样您就可以更好地控制JSON。修改实体的主键也会导致灾难。还请记住,作为托管实体的merge的返回值,而不是要合并的输入。我支持Klaus,您不应该直接从实体自动生成JSON。手动生成或使用某种中间DTO。
detach
用于跨会话操作。不要使用
detach
仅仅是为了能够以Hibernate不期望的方式操作对象。Hibernate没想到会这样!另外,您的代码在
分离
之后的任何地方都不使用
合同
,因此我不知道您想做什么。对不起,我可能已经说得更清楚了。我马上就要编辑了。我有一个用于插入的嵌入式id,但我不希望它们以实际的JSON返回。所以我有两个同名的临时字段,我只是移动它们——但是在我更新之后。我不希望在JSON中返回密钥,这本质上是我的目标。我会发布更多的代码示例,让您有更好的想法。您需要提供更多的代码。您有一个引用实体的契约变量,但我看不到该变量的其他用途。您确定要使用合并吗?我从不使用我的实体来生成JSON,但为此我有一组单独的DTO类,这样您就可以更好地控制JSON。修改实体的主键也会导致灾难。还请记住,作为托管实体的merge的返回值,而不是要合并的输入。我支持Klaus,您不应该直接从实体自动生成JSON。手工生成或使用某种中间DTO。非常有用。我可能太多地从Java的角度来看待这个问题。谢谢,非常有帮助。我可能太多地从Java的角度来看待这个问题。谢谢