繁体   English   中英

如何在Grails中的运行时创建有效的Domain对象

[英]How to create valid Domain objects at runtime in Grails

我有一些域类,我希望能够填充一个新的Domain类并通过我的一个控制器将其持久化到数据库中。 这是我的课

class Employee implements Comparable
{
    static hasMany = [education:Education]
    static mapping = {
        education cascade:"all,delete-orphan", lazy:false
    }
    List<Education> education = new ArrayList<Education>();
}


public class Education implements Comparable
{
   static belongsTo = [employee:Employee]
   String collegeName
   String areaOfStudy
   String yearGranted
   Date lastModified
   Boolean inProcess = false;
   EducationType type = new EducationType(name:"None");
}


class EducationType
{
    String name="";
}

现在,我想从此控制器为特定员工创建一个新的Education条目。

        def employee = Employee.get(session.empid);
        EducationType et = new EducationType(name:'JD')
        Education ed1 = new Education(collegeName:'Harvard1', areaOfStudy:'Law', yearGranted:'2015', type:et, lastModified:new Date(), employee:employee)

        employee.addToEducation(ed1)
        employee.save()

出于某种原因,这无法达到预期的效果,并且出现了以下异常:

2010-09-24 10:56:01,503 [http-8080-1] ERROR errors.GrailsExceptionResolver  - not-null property references a null or transient value: Education.type; nested exc
eption is org.hibernate.PropertyValueException: not-null property references a null or transient value: Education.type
org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: Education.type; nested exception is org.hiberna
te.PropertyValueException: not-null property references a null or transient value: Education.type
        at org.jsecurity.web.servlet.JSecurityFilter.doFilterInternal(JSecurityFilter.java:382)
        at org.jsecurity.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:180)
        at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: Education.type
        ... 3 more

通过首先使用et.save()保存EducationType,然后使用ed.save()保存Education对象,最后保存员工,我可以解决这个问题。

为什么这是必要的? 我的映射是否表示节省员工的精力应该滴流到现在与该员工相关联的所有非持久对象上?

另外-为什么在初始化Education对象时必须显式添加员工? 它是在belongsTo对象中指定的,并且当我执行employee.addToEducation()调用时,应该自动将其拾取,对吗?

谢谢!

您的Education to EducationType被定义为简单的一对一。 要从Education转换为EducationType,我认为您可以使后者属于前者。 请查阅用户指南5.2.1.1。 请注意,您必须小心要使用的持久性语义? 您是否真的希望EducationTypes成为自己的实体?

我认为您必须将员工添加到教育中,因为您具有双向一对多的关系。 关系的双方都必须建立。 addToEducation可以将集合的成员添加到关系的拥有方。 显然,它没有设置从拥有方到拥有方的关系。

----编辑----

我只是看了看文档,因为您的第二个错误似乎很奇怪

“ addTo *方法是一种动态方法,它使用关联自动将实例添加到关联中。它还自动配置双向关系,以便已设置了关联的双方。”

因此,似乎addTo应该设置关系的两面...如果您将雇员:雇员从您的Education创造中删除,这行不通吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM