【问题标题】:"org.springframework.dao.InvalidDataAccessApiUsageException: Multiple representations of the same" when running Spring Integration Test运行 Spring 集成测试时出现“org.springframework.dao.InvalidDataAccessApiUsageException: Multiple representations of the same”
【发布时间】:2017-01-30 22:31:46
【问题描述】:

我遇到了一个奇怪的问题,我不确定解决问题的最佳方法是什么。我写了一些JPA 实体类,它们可以很好地保存到数据库中,但是当我在Spring JUnit 环境中运行时,出现以下异常:

org.springframework.dao.InvalidDataAccessApiUsageException:多个 同一实体 [com..x.y.z.Address#0] 的表示正在 合并。已分离:[com..x.y.z.Address@48d9d51f];管理: [com..x.y.z.Address@4a5e389b];嵌套异常是 java.lang.IllegalStateException:相同的多个表示 实体 [com..x.y.z.Address#0] 正在合并。分离式: [com..x.y.z.Address@48d9d51f];托管:[com..x.y.z.Address@4a5e389b]

我的实体类类似如下:

class User {

   @Id   
   @SequenceGenerator(name = "USER_ID_GENERATOR", sequenceName = "USER_SEQ")
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_ID_GENERATOR") 
   private String id;

   @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   private Set<Address> addresses = new HashSet<>();
}

class Address{
  @Id
  private long addressId;

  private String addressLine;

  @ManyToOne 
  @JoinColumn(name="user_id") 
  private User user;
}

我想补充一点,我正在使用 Spring JPA 的 CrudRepository 进行保存。

我的测试的简单再现如下:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {MyApplication.class})
@WebIntegrationTest({ "server.port=12345", "server.url=http://127.0.0.1:12345" })
@DirtiesContext
public class MyIntegrationTest {

 private UserRepository userRepository

 @Test
 public void testSave(){
   User user = new User(1, "James");
   Address address1 = new Address("1234 xyz street");
   user.addAddress(address1);

   userRepository.save(user);

   User user = userRepository.findById(1);
   Address address2 = new Address("111 abc street");
   user.addAddress(address2);
   userRepository.save(user) // this is where the exception happens while running the test
 }
}

我应该怎么做才能使它在我的测试和实际运行环境中都能正常运行?谢谢

【问题讨论】:

  • 向我们展示您的测试
  • 我对如何创建地址实例和填充数据特别感兴趣
  • 我已经用您正在寻找的信息更新了我的问题
  • 还好一件事.. 我想要地址实体上的@Id 映射

标签: java spring jpa spring-data-jpa spring-junit


【解决方案1】:

好吧,我是这么看的..

您的 Address 实体有一个没有任何生成策略的 @Id,因此其中的任何内容都将被视为主键。

您对用户到地址的所有操作级联:

@OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)

所以我猜你第二次保存用户时,它实际上是先尝试合并..

现在,您创建两个 Address 实例而不指定 id.. 所以在这两种情况下都将是 0。您先保存,这很好,您检索用户以及第一个地址(因为 EAGER 获取),然后您创建另一个地址,并且 id 将再次是相同的0。

现在你在列表中得到了两个具有相同 id 的地址。一个由持久上下文管理,另一个被分离。 在合并期间,您会收到该错误。

我无法 100% 证明这一点,但我有预感,如果您将地址的 id 分别指定为 1 和 2(或任何两个不同的),您将不会再看到该错误。

【讨论】:

  • 我想你可能有一个好点,让我试试,会告诉你
  • 谢谢先生!一旦我确保两个 Address 实例具有不同的 ID,就可以了!非常感谢!
猜你喜欢
  • 2019-07-16
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-19
  • 2018-11-07
相关资源
最近更新 更多