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

时间:2010-09-24 14:59:31

标签: hibernate 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="";
}

现在我想从这个控制器为特定员工创建一个新的教育条目。

        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对象并最终保存员工来消除此问题。

为什么这有必要?我的映射是否表示对员工的保存应该渗透到现在与员工关联的任何非持久对象?

另外 - 为什么我在初学教育对象时必须明确添加员工?它在belongsTo对象中指定,看起来当我执行employee.addToEducation()时,它应该自动拾取,对吧?

谢谢!

1 个答案:

答案 0 :(得分:0)

您的Education to EducationType被定义为简单的一对一。从教育到教育类型的级联,我认为你可以使后者属于前者。查看用户指南的5.2.1.1。注意你必须小心你想要的持久性语义?你真的希望EducationTypes成为他们自己的实体吗?

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

----编辑----

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

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

所以似乎addTo应该设置关系的两个方面......如果你把员工:员工从你的教育创建中取出它不起作用?