In-Memory 和 MySQL 数据库的不同持久性行为
Different Persistance Behaviour with In-Memory and MySQL DB
我有一个 parent 实体和一个具有一对多关系的 child 实体。
当使用@DataJpaTest(即配置内存数据库)时,以下按预期工作:
LOG.info("Creating stops");
Stop stop1 = new Stop(new Time(0), "Acton Town", new HashSet<>());
Set<Stop> stops = new HashSet<>();
stops.add(stop1);
LOG.info("Creating and persisting routes");
Route route = routeRepository.save(new Route("something", "return"));
LOG.info("Adding stops to route");
stops.forEach(route::addStop);
它正确地插入了路线和每个child,我可以稍后获取路线并获得相同的信息。
但是,当我在使用真实数据源(本地 MySQL 数据库)的服务中重复此操作时,CASCADE.ALL 持久化似乎并没有发生,我最终没有插入对于停靠点,但路线会保留并分配一个 ID。
我听从了网站周围的建议,在配置双向关系的 parent 中使用了 'addEntity' 方法,但它在测试套件之外不起作用。
有人知道这是为什么吗?
所以我的测试和我的服务之间的区别之一是 entityManager.flush() 的使用。
通过将@Transactional 添加到我的服务方法,children 得到持久化,因为这将方法调用包装在 AOP 代理中,本质上是这样做的:
transaction.begin()
service.method()
transaction.commit()
我的 children 似乎没有被持久化,因为我基本上没有告诉休眠什么时候去做。
我之前在其他服务中没有注意到它的原因是我使用 CrudRepository 来保存实体,这将确保立即填充 id 字段,因此这实际上会提交事务。
它也可能受到我工作的 multi-tenant 环境的影响,我有多个事务管理器。如果是这种情况,您可能必须指定带有事务注释的一个,如下所示:
@Transactional("nameoftransactionmanager")
我有一个 parent 实体和一个具有一对多关系的 child 实体。
当使用@DataJpaTest(即配置内存数据库)时,以下按预期工作:
LOG.info("Creating stops");
Stop stop1 = new Stop(new Time(0), "Acton Town", new HashSet<>());
Set<Stop> stops = new HashSet<>();
stops.add(stop1);
LOG.info("Creating and persisting routes");
Route route = routeRepository.save(new Route("something", "return"));
LOG.info("Adding stops to route");
stops.forEach(route::addStop);
它正确地插入了路线和每个child,我可以稍后获取路线并获得相同的信息。
但是,当我在使用真实数据源(本地 MySQL 数据库)的服务中重复此操作时,CASCADE.ALL 持久化似乎并没有发生,我最终没有插入对于停靠点,但路线会保留并分配一个 ID。
我听从了网站周围的建议,在配置双向关系的 parent 中使用了 'addEntity' 方法,但它在测试套件之外不起作用。
有人知道这是为什么吗?
所以我的测试和我的服务之间的区别之一是 entityManager.flush() 的使用。
通过将@Transactional 添加到我的服务方法,children 得到持久化,因为这将方法调用包装在 AOP 代理中,本质上是这样做的:
transaction.begin()
service.method()
transaction.commit()
我的 children 似乎没有被持久化,因为我基本上没有告诉休眠什么时候去做。
我之前在其他服务中没有注意到它的原因是我使用 CrudRepository 来保存实体,这将确保立即填充 id 字段,因此这实际上会提交事务。
它也可能受到我工作的 multi-tenant 环境的影响,我有多个事务管理器。如果是这种情况,您可能必须指定带有事务注释的一个,如下所示:
@Transactional("nameoftransactionmanager")