【发布时间】:2018-11-09 10:32:22
【问题描述】:
我有一个小示例,其中包含 Spring Boot 中的一些 get/post 映射和 JpaRepository 调用。
首先我有两个实体类:
@Entity
@Table(name = "stock")
public class Stock extends BaseEntity
{
@Column(name = "value")
public String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@Entity
@Table(name = "stock_item")
public class StockItem extends BaseEntity
{
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "stock_id", insertable = false, updatable = false)
public Stock stock;
@Column(name = "stock_id")
public Long stockId;
@Column(name = "value")
public String value;
}
我有一个从 StockItem 到 Stock 的多对一关联。
我插入一个Stock 并有一个控制器如下:
@Autowired
public Controller(StockItemRepository stockItemRepository) {
this.stockItemRepository = stockItemRepository;
}
@RequestMapping("/")
@Transactional(readOnly = true)
public String get() {
List<StockItem> stockItemList = stockItemRepository.getItemsById(1L);
System.out.println("TX MANAGER: " + TransactionSynchronizationManager.isActualTransactionActive());
for (StockItem stockItem : stockItemList) {
System.out.println(stockItem.getStock().getValue());
}
return "get";
}
@RequestMapping("/fromSave")
@Transactional
public String post() {
StockItem stockItem = new StockItem();
stockItem.setStockId(1L);
stockItemRepository.saveAndFlush(stockItem);
System.out.println("saveCalled");
return get();
}
和getItemsById在仓库中的定义如下:
@Query("FROM StockItem si " +
"JOIN FETCH si.stock stk " +
"WHERE si.stockId = :id")
List<StockItem> getItemsById(@Param("id") Long id);
据我了解,当我调用 post 方法时:
- 它会创建一个新项目
- 设置关联属性的id
- 保存并结束交易
这就是事情变得奇怪的地方......
我在帖子之后调用 get 并进行上述存储库调用,它有一个 join fetch,当我调用 stockitem.getStock().getValue() 时,当我期望 LazyInitializationException 时,我得到一个空指针。
如果我在类外部从映射中调用get(),它会成功加载关联的对象。
我什至从 get 中删除了 @Transaction 注释,以及
再次从我的查询中获取连接,如果我从它工作的类之外和从帖子中调用它,它会崩溃并显示NullPointerException。
我已将get 放在TransactionTemplate.execute() 中,当从班级内部调用时,我仍然得到NullPointerException。
所以主要问题是:
- 为什么我得到的是
NullPointerException而不是LazyInitializationException? - 没有事务但成功获取惰性属性背后的事务魔法是什么??
【问题讨论】:
标签: spring-boot spring-data-jpa spring-transactions