内存和MySQL DB的不同持久性行为

时间:2018-07-10 11:30:38

标签: spring hibernate spring-data-jpa h2 hibernate-cascade

我有一个具有一对多关系的父实体和一个子实体。

在使用@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);

它会正确插入路线和每个孩子,我稍后可以获取路线并获得相同的信息。

但是,当我在使用真实数据源(本地MySQL数据库)时在服务中重复此操作时,似乎没有发生CASCADE.ALL持久化,并且我最终没有插入任何停靠点,但路由仍然存在并分配了一个ID。

我遵循了来自站点周围的建议,在配置双向关系的父级中使用了“ addEntity”方法,但是在测试套件之外它不起作用。

有人知道为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

因此,我的测试和服务之间的区别之一是使用entityManager.flush()。

通过将@Transactional添加到我的服务方法中,这些子项将保持持久状态,因为这将方法调用包装在AOP代理中,该代理实际上执行了以下操作:

transaction.begin()
service.method()
transaction.commit()

似乎我的孩子并没有被坚持,因为我基本上没有告诉冬眠何时做。

我之前在其他服务中没有注意到它的原因是,我正在使用CrudRepository保存实体,以确保可以立即填充id字段,因此这实际上将提交事务。

它可能还会受到我正在工作的多租户环境的影响,我在那里有多个事务管理器。如果您是这种情况,则可能需要像下面这样指定带有事务处理注释的对象:

@Transactional("nameoftransactionmanager")