我们正在处理由Spring Roo生成的GWT项目,但我们不再使用Roo来编辑/生成类。相反,我们现在全部手动编写。
对于每个服务器端实体类,Roo生成了相当奇怪的EntityManager获取代码。我希望能够很好地理解它,但事实上并没有。以下是生成实体代码的片段:
对于每个服务器端实体类,Roo生成了相当奇怪的EntityManager获取代码。我希望能够很好地理解它,但事实上并没有。以下是生成实体代码的片段:
@PersistenceContext
transient EntityManager entityManager;
public static final EntityManager entityManager() {
EntityManager em = new Scenario().entityManager;
if (em == null)
throw new IllegalStateException(
"Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
return em;
}
@Transactional
public void persist() {
if (entityManager == null)
entityManager = entityManager();
entityManager.persist(this);
}
public static List<Scenario> findAllScenarios() {
List<Scenario> res = entityManager().createQuery(
"select o from Scenario o order by o.name",
Scenario.class).getResultList();
return res;
}
public static Scenario findScenario(Long id) {
if (id == null)
return null;
return entityManager().find(Scenario.class, id);
}
我的观察和问题:
- 实例方法使用由Spring注入的
EntityManager
字段,这很清楚。但是这一行代码:if(entityManager == null) entityManager = entityManager();
是干什么用的呢?我们不是期望在em
字段中注入EntityManager
且不能为null
吗(否则就有问题了)? - 静态方法创建实体类的新实例并获取其
EntityManager
字段,为什么要这样做呢?EntityManager
不能缓存在静态字段中吗? - 为什么像
findAllXXX
这样的读取方法没有@Transactional
注解?据我所知,根据JPA规范,所有JPA操作都应该在事务范围内执行? findXXX
方法中的if (id == null) return null;
代码段真的必要吗?如果我们得到null
作为id
参数,难道不应该崩溃应用程序以显示出现问题了吗?- 我们能否以更优雅的方式重写这个
EntityManager
获取代码(例如,不使用奇怪的new Entity().entityManager
这种方法),但同时不破坏它(可能需要保留某些前提条件)? - 为什么
EntityManager
字段是transient
的?这很重要吗?