在play framework 1.2.x, class JPABase分析中,为啥要调用saveAndCascade()?
Posted
技术标签:
【中文标题】在play framework 1.2.x, class JPABase分析中,为啥要调用saveAndCascade()?【英文标题】:in play framework 1.2.x , class JPABase analysis , why does it use the call saveAndCascade()?在play framework 1.2.x, class JPABase分析中,为什么要调用saveAndCascade()? 【发布时间】:2013-10-28 13:54:01 【问题描述】: public void _save()
if (!em().contains(this))
em().persist(this);
PlayPlugin.postEvent("JPASupport.objectPersisted", this);
avoidCascadeSaveLoops.set(new ArrayList<JPABase>());
try
saveAndCascade(true);
finally
avoidCascadeSaveLoops.get().clear();
try
em().flush();
catch (PersistenceException e)
if (e.getCause() instanceof GenericJDBCException)
throw new PersistenceException(((GenericJDBCException) e.getCause()).getSQL());
else
throw e;
avoidCascadeSaveLoops.set(new ArrayList<JPABase>());
try
saveAndCascade(false);
finally
avoidCascadeSaveLoops.get().clear();
private void saveAndCascade(boolean willBeSaved)
this.willBeSaved = willBeSaved;
if (avoidCascadeSaveLoops.get().contains(this))
return;
else
avoidCascadeSaveLoops.get().add(this);
if (willBeSaved)
PlayPlugin.postEvent("JPASupport.objectUpdated", this);
// Cascade save
try
Set<Field> fields = new HashSet<Field>();
Class clazz = this.getClass();
while (!clazz.equals(JPABase.class))
Collections.addAll(fields, clazz.getDeclaredFields());
clazz = clazz.getSuperclass();
for (Field field : fields)
field.setAccessible(true);
if (Modifier.isTransient(field.getModifiers()))
continue;
boolean doCascade = false;
if (field.isAnnotationPresent(OneToOne.class))
doCascade = cascadeAll(field.getAnnotation(OneToOne.class).cascade());
if (field.isAnnotationPresent(OneToMany.class))
doCascade = cascadeAll(field.getAnnotation(OneToMany.class).cascade());
if (field.isAnnotationPresent(ManyToOne.class))
doCascade = cascadeAll(field.getAnnotation(ManyToOne.class).cascade());
if (field.isAnnotationPresent(ManyToMany.class))
doCascade = cascadeAll(field.getAnnotation(ManyToMany.class).cascade());
if (doCascade)
Object value = field.get(this);
if (value == null)
continue;
if (value instanceof PersistentMap)
if (((PersistentMap) value).wasInitialized())
for (Object o : ((Map) value).values())
if (o instanceof JPABase)
((JPABase) o).saveAndCascade(willBeSaved);
continue;
if (value instanceof PersistentCollection)
if (((PersistentCollection) value).wasInitialized())
for (Object o : (Collection) value)
if (o instanceof JPABase)
((JPABase) o).saveAndCascade(willBeSaved);
continue;
if (value instanceof HibernateProxy && value instanceof JPABase)
if (!((HibernateProxy) value).getHibernateLazyInitializer().isUninitialized())
((JPABase) ((HibernateProxy) value).getHibernateLazyInitializer().getImplementation()).saveAndCascade(willBeSaved);
continue;
if (value instanceof JPABase)
((JPABase) value).saveAndCascade(willBeSaved);
continue;
catch (Exception e)
throw new UnexpectedException("During cascading save()", e);
为什么它使用调用 saveAndCascade()? 我查看了源代码,但我无法理解。 任何帮助表示赞赏。
我想学习playframework的使用方法,但是看不懂。我看了Play+Framework+Cookbook和Wayne Ellis - Introducing the Play Framework,但是找不到关于play源码的分析。 任何书籍、文档或声明都将受到赞赏。
【问题讨论】:
【参考方案1】:在正常的 JPA 环境中,EntityManager.flush() 方法将检查所有加载的实体,如果它们被修改 - 更改将保存回数据库。
Play-1 的工作方式不同 - 此函数设置 willBeSaved 变量,稍后 Hibernate 拦截器会检查它并仅允许更新此特定实体,因此如果有其他修改过的实体 - 它们不会更新。
【讨论】:
以上是关于在play framework 1.2.x, class JPABase分析中,为啥要调用saveAndCascade()?的主要内容,如果未能解决你的问题,请参考以下文章
如何将参数传递给 Play 中的 Jobs!框架 1.2.x?
Play Framework:如何不查看文件夹以了解 Play Framework 中的更改
在 Play framework 2.3 中设置 cookie sameSite