5

Grails GORMは、抽象ドメインクラスをデータベースに永続化しないため、多態的な関係が失われます。例えば:

abstract class User {
    String email
    String password
    static constraints = {
        email(blank:false, nullable:false,email:true)
        password(blank:false, password:true)
    }

    static hasMany = [membership:GroupMembership]
}

class RegularEmployee extends User {}

class Manager extends User {
    Workgroup managedGroup
}

class Document {
    String name
    String description
    int fileSize
    String fileExtension
    User owner
    Date creationTime
    Date lastModifiedTime
    DocumentData myData
    boolean isCheckedOut
    enum Sensitivity {LOW,MEDIUM,HIGH}
    def documentImportance = Sensitivity.LOW

    static constraints = {
        name(nullable:false, blank:false)
        description(nullable:false, blank:false)
        fileSize(nullable:false)
        fileExtension(nullable:false)
        owner(nullable:false)
        myData(nullable:false)
    }
}

原因

原因:org.hibernate.MappingException:テーブルドキュメントからの関連付けがマップされていないクラスを参照しています:User ... 25 more 2009-11-11 23:52:58,933[main]エラーmortbay.log-org.springframeworkにネストされています.beans.factory.BeanCreationException:「messageSource」という名前のBeanの作成中にエラーが発生しました:Beanの初期化に失敗しました。ネストされた例外はorg.springframework.beans.factory.BeanCreationExceptionです:「transactionManager」という名前のBeanの作成中にエラーが発生しました:Beanプロパティ「sessionFactory」の設定中にBean「sessionFactory」への参照を解決できません。ネストされた例外はorg.springframework.beans.factory.BeanCreationExceptionです:「sessionFactory」という名前のBeanの作成中にエラーが発生しました:initメソッドの呼び出しに失敗しました。ネストされた例外はorg.hibernate.MappingExceptionです:

しかし、このシナリオでは、システムのすべてのユーザーを定義された役割の1つに適合させながら、すべてのユーザーがドキュメントを所有できるようにするという多態的な効果が必要です。したがって、ユーザーは直接インスタンス化されるべきではなく、抽象化されます。

非抽象ユーザークラスのロールに列挙型を使用したくないのは、特定のコンテキストでは意味をなさない可能性のある、さまざまなロールにプロパティを追加できるようにするためです(ロールがRegularEmployeeに設定されている単一のユーザーで、何らかの理由でnullではないmanagedGroupを取得します)。

これはGrailsのバグですか?私は何かが足りないのですか?

4

2 に答える 2

3

Shiro、Nimble (Shiro を使用)、Spring Security プラグインのドメイン モデルを表示することをお勧めします。具体的なユーザー ドメインと具体的な役割ドメインを作成します。特に Shiro は、多対多マッピング用の UserRole ドメインを作成します。

次に、Role ドメインで、必要なプロパティを追加できます。必要に応じて、別のドメインを作成して、次のように任意のプロパティを許可できます。

class Role {
    //some properties
    static hasMany = [roleProperties:RoleProperty, ...]
}

class RoleProperty {
    String name
    String value
    static belongsTo = [role:Role]
}

ただし、現在のドメイン マッピングで探しているものが得られるとは思いません。

于 2009-11-12T14:44:01.380 に答える
2

先日、ポリモーフィズムを調べるために職場で Grails の継承階層をテストしていました。次のシナリオが見つかりました。

抽象スーパークラス - サブクラスは親の動作を継承しますが、親を使用してデータベースに格納するサブクラスを参照することはできません。

tablePerHeirarchy が false のスーパークラス - サブクラスは親のフィールドを親のテーブルに格納し、ポリモーフィズムは期待どおりに機能します。

tablePerHeirarchy が false の空のスーパークラス - サブクラスは独自のデータをすべてテーブルに格納し、ポリモーフィズムは期待どおりに機能します。

したがって、あなたの場合、ユーザークラスからabstractキーワードを削除すると、すべてが期待どおりに機能します。唯一の欠点は、すべての User フィールドが User テーブルに格納され、RegularEmployee テーブルには id 列と version 列のみがあり、Manager テーブルには Workgroup 行への参照しかないことです。

于 2009-11-13T01:32:36.787 に答える