简体   繁体   English

Grails中的多对多关系

[英]Many-to-Many Relationship in Grails

I am writing a basic web application with grails using hibernate w/ MySQL and vaadin, spring security, and spring security acl plugins that is used to manage Committees, Members, and memberships between Committees and Members. 我正在使用Grails使用w / MySQL和vaadin,spring security和spring security acl插件编写带有grails的基本Web应用程序,该插件用于管理委员会,成员以及委员会与成员之间的成员资格。 All of the CRUD works for both Members and Committees, but when I create a CommitteeMember object, it has trouble referencing the Member field of the class to get information about the member involved in the membership. 所有CRUD都适用于成员和委员会,但是当我创建一个CommitteeMember对象时,它很难引用类的Member字段来获取有关成员资格成员的信息。 Here are my classes: 这是我的课程:

class Committee {
    String name
    String description
    String bylaws
    static hasMany = [members: CommitteeMember]
    static constraints = {
        name blank: false, nullable: false, matches: "[a-zA-Z0-9 ]*", unique: true
        description blank: false, nullable: false, matches: "[a-zA-Z0-9 ]*"
        bylaws blank: false, nullable: false, matches: "[a-zA-Z0-9 ]*"
   }
}

class Member {
    String firstName
    String middleName
    String lastName
    String address
    String phone

    static hasMany = [committees: CommitteeMember]
    static constraints = {
        firstName blank: false, nullable: false, matches: "[a-zA-Z]*"
        middleName blank: false, nullable: false, matches: "[a-zA-Z]*"
        lastName blank: false, nullable: false, matches: "[a-zA-Z]*"
        address blank: false, nullable: false, matches: "[0-9a-zA-Z ]*"
        phone blank: false, nullable: false, minSize: 10, maxSize: 10, matches: "[0-9]*"
    }
}

class CommitteeMember {

    Member member
    Committee committee
    Date startDate
    Date endDate
    String title
    Date created = new Date()
    Date updated = new Date()

    static constraints = {
        startDate blank: false, nullable: false, format: 'mm/dd/yyyy'
        endDate blank: false, nullable: false, format: 'mm/dd/yyyy'
        title blank: false, nullable: false, matches: "[a-zA-Z0-9 ]*"
        created blank: false, nullable: false, editable: false, display: false
        updated blank: false, nullable: false, editable: false, display: false
    }

}

And the methods of the service layer that add these classes: 以及添加这些类的服务层的方法:

@Transactional
def saveCommittee(name, desc, bylaws) {
    new Committee(name: name, description: desc, bylaws: bylaws).save(flush: true);
}

@Transactional
def saveMember(fname, mname, lname, address, phone) {
    new Member(firstName: fname, middleName: mname, lastName: lname,
                 address: address, phone: phone).save(flush: true);
}

@Transactional
def saveCommitteeMember(cname, lname, fname, title, start, end) {
    def cmem = new CommitteeMember(title: title, startDate: start, endDate: end);
    cmem.member = Member.findByLastNameAndFirstName(lname, fname);
    cmem.committee = Committee.findByName(cname);
    cmem.save(flush: true);
}

Creating these classes works, and they are stored in the database. 创建这些类是可行的,并将它们存储在数据库中。 My update and delete methods work great for the members and the committees. 我的更新和删除方法非常适合会员和委员会。 But, when I try to something like 但是,当我尝试类似

//this works
def cm = CommitteeMember.get(1);
def title = cm.title;

//this does not
def firstName = cm.member.firstName;

none of the fields of the Member referenced by the Committee member are accessible. 委员会成员所引用的成员字段均不可访问。 What am I doing wrong here? 我在这里做错了什么? I've done lots of research and can't find anything exactly like this. 我已经做了大量研究,找不到完全像这样的东西。 Help would be GREATLY appreciated. 帮助将不胜感激。 Pulling my hair out over this thing.. 把头发拉过来。

**UPDATE **更新

In the service layer method saveCommitteeMember() , I added a line println(cmem.member.firstName); 在服务层方法saveCommitteeMember() ,我添加了一行println(cmem.member.firstName); , and in the terminal where my grails is launching, it indeed does print the first name of the member that I added to a committee when I call the function. ,并且在启动grails的终端中,它确实会打印我在调用该函数时添加到委员会的成员的名字。

JESUS. 耶稣。 I finally figured it out. 我终于弄明白了。 Ok, here it what was happening. 好的,这里发生了什么。 Hibernate does findByFirstNameAndLastName() , and that works fine, but since grails is LAZY by default, it only returns a REFERENCE to that Member object, and not an object representation of the data within the table. Hibernate确实使用findByFirstNameAndLastName() ,并且工作正常,但是由于grails默认为LAZY,因此它仅返回对该Member对象的REFERENCE,而不返回表中数据的对象表示。 This reference is destroyed when the function returns, and the CommitteeMember object is left with its member field pointing to nothing. 当函数返回时,此引用被销毁,而CommissionMember对象的成员字段不指向任何内容。 This is especially great, because using the Vaadin plugin, you don't get the LazyInitializationException - no session exists or whatever that error message is unless you are explicitly trying to reference something from a @Transaction, so doing def fname = cm.member.firstName wasn't throwing said exception, because the @Transaction was thought of as a success, and I was simply trying to read a null value, which resulted in no error message whatsoever other than termination of the function in which the error occurred. 这特别好,因为使用Vaadin插件不会得到LazyInitializationException - no session exists或任何错误消息,除非您明确尝试引用@Transaction中的某些内容,所以执行def fname = cm.member.firstName不会抛出该异常,因为@Transaction被认为是成功的,而我只是在尝试读取一个空值,除了终止发生错误的函数外,它不会导致任何错误消息。 Talk about some serious bull#$&%! 谈论一些严重的公牛#$&%!

Anyways, to FIX this ridiculous issue, add this to the objects you are having null issues with 无论如何,要解决这个荒谬的问题,请将其添加到您存在空问题的对象中

class CommitteeMember {

    Member member
    Committee committee
    etc......

    static mapping = {
        member lazy: false
        committee lazy: false
    }

}

I REALLY hope that anyone else who has a problem like this finds this post. 我真的希望其他人遇到这样的问题。 This has cost me loads of time on something so ridiculous. 这花了我很多时间在如此荒谬的事情上。 Lazy evaluation is super nice in some situations. 在某些情况下,惰性评估非常好。 Database operations, IMO, are not those type of situations. IMO数据库操作不是这种情况。 Anyways, cheers. 无论如何,欢呼。

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

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