2013-10-25 23 views
0

我是Grails和GORM的新手,但是我在傳統的PostgreSQL上有一箇舊的JPA2(Hibernate)應用程序來映射,但是我無法獲得繼承的抽象類的工作,這裏是問題的一個例子,讓我們用這個表:Grails/GORM 2.3尋找抽象域類的Hibernate持久表

users (id serial, username varchar, password char(44), user_modified integer, last_modified timestamp); 
roles (id serial, role varchar, description varchar, enabled boolean, user_modified integer, last_modified timestamp); 
permissions (user_id integer, role_id integer, enabled boolean); 

正如你可以看到表採用數字自動遞增的ID,但是這並不適用於所有的人,對舊JPA映射我使用@MappedSuperclass來映射ID配置,如id生成器和一些審計列:

@MappedSuperclass 
public abstract class DefId { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    protected Long id; 

    @NotNull 
    @Column(name = "user_modified") 
    protected Long userModified; 

    @Version 
    @Column(name = "last_modified") 
    @Source(SourceType.DB) 
    protected Date lastModified; 

    //getters and setters 
} 

以下是我在Grails的到目前爲止已經試過:

DefId.groovy:

abstract class DefId { 
    /*In the actual source this are protected fields 
    with public getters/setters removed for less code*/ 
    Long id; 
    Long userModified; 
    Timestamp version; 

    static mapping = { 
     id generator: 'identity' 
     version 'last_modified' 
     userModified column: 'user_modified' 
    } 
} 

User.groovy:

package maptest.domain 

import maptest.model.DefId 

class User extends DefId { 
    String username 
    String password 
    boolean enabled 
    static hasMany = [roles: Role]; 

    static mapping = { 
     table name: "users", schema: "core" 
     roles joinTable: [name: "permissions", key: "user_id"] 
    } 

    static constraints = { 
     username blank: false, size: 2..20, matches: "^[A-Za-z]\\w+\$", unique: true 
     password blank: false, matches: "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?\$" 
     preferences unique: true 
    } 
} 

Role.groovy

package maptest.domain 

import maptest.domain.DefId 

class Role extends DefId{ 
    String role 
    String description 
    boolean enabled 

    static hasMany = [users: User]; 
    static belongsTo = [User]; 

    static mapping = { 
     table name: "roles", schema: "core" 
     users joinTable: [name: "permissions", key: "role_id"] 
    } 
    static constraints = { 
     role blank: false, size: 2..20, matches: "^[A-Za-z]\\w+\$", unique: true 
     description size: 2..50 
    } 
} 

如果我離開領域結構中的抽象類,我得到了異常:org.springframework.jdbc.BadSqlGrammarException: Hibernate operation: ERROR: relation "def_id" don't exists;這是真的,但我沒有試圖堅持抽象類。

如果我更改包和移動抽象類爲src /常規後來我:org.springframework.orm.hibernate4.HibernateSystemException: Unknown entity: mapetest.domain.User;

我也嘗試添加grails.gorm.default.mapping = {id生成:「身份」}到Config.groovy並從超類中刪除id字段,但這隻會讓我又有一個錯誤:Error loading plugin manager: Identity property not found, but required in domain class [maptest.domain.Role]

任何人有什麼想法?將id生成器:​​'identity''添加到每個單獨的域類中,解決它,但是這會破壞繼承的目的。

原諒我的英語,這是第二語言

+0

我開始認爲,grails hibernate插件不應用純jpa MappedSuperclass的相同概念,而是顯示它假定實體中的抽象類。一個擴展另一個的實體並不是一個擴展MappedSuperClass –

回答

1

把你的抽象類中域類的文件夾。您還需要告訴Grails的每班考慮不同的表:

static mapping = { 
    tablePerSubclass true 
} 

默認是唯一一家擁有class列的表。

您也不需要聲明id字段,因爲它是由Grails自動生成的,其類型爲Long

+1

的實體,但它沒有起作用我添加了'tablePerSubclass true'並從defId類中刪除了id屬性,但仍有第一種情況:'org.springframework.jdbc .BadSqlGrammarException:Hibernate操作:錯誤:關係「def_id」不存在;' –