GORM组合 - 具有多对一关系的嵌入式域抛出org.hibernate.MappingException

时间:2013-04-16 21:34:28

标签: hibernate grails gorm

我正在尝试在Grails 2.2.1中使用具有多对一关系的嵌入式域。这是我想要做的简化版本。

我正在映射到现有的数据库表:

create table incident (id bigint generated by default as identity, state_id bigint not null, primary key (id));
create table state (id bigint generated by default as identity, name varchar(255) not null, primary key (id));
alter table incident add constraint FK52F44D27499E79E foreign key (state_id) references state;

映射到“事件”表的域:

class Incident {
    Vehicle vehicle
    static embedded = ['vehicle']
}

class Vehicle{
    State state
    static mapping = {
        state column: 'state_id'
    }   
}  

映射到“州”表的域:

class State {
    String name 
}

当我尝试运行我的应用程序时,出现以下错误:

  

消息:创建名为'transactionManagerPostProcessor'的bean时出错:bean的初始化失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'transactionManager'的bean时出错:在设置bean属性'sessionFactory'时无法解析对bean'sessionFactory'的引用;嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'sessionFactory'的bean时出错:init方法的调用失败;嵌套异常是 org.hibernate.MappingException:无法确定:test.State的类型,在table:incident,对于列:[org.hibernate.mapping.Column(vehicle_state)]

是否可以在嵌入式域中建立多对一关联?

- 的更新 -

我最终使用了一种解决方法来获取状态。

class Vehicle{

    static transients = [ "state" ]

    Long stateId

    static mapping = {
        stateId column: 'state_id'  
    }

    State getState(){
        State.get(this.stateId)
    }
}

2 个答案:

答案 0 :(得分:4)

从Grails 2.2.1开始,嵌入式域类有几个可用性问题,使得它们难以使用,尤其是在旧数据库中。

  1. 关系不起作用
  2. 自定义列映射不起作用
  3. 最好直接在拥有类中映射列,然后创建一个帮助方法来处理嵌入的实体。

    e.g:

    // grails-app/domain/yourpkg/Incident.groovy
    class Incident {
        State state
    
        public Vehicle getVehicleData() {
            return new Vehicle(state: state)
        }
    
        public void updateWithVehicle(Vehicle vehicle) {
            state = vehicle.state
        }
    
        static mapping = {
            state column: 'state_id'
        }
    }
    
    // src/groovy/yourpkg/Vehicle.groovy
    class Vehicle {
        State state
    }
    

答案 1 :(得分:0)

在这种情况下,域名必须为serialized(包括嵌入式Vehicle,如果移至src/groovy并且生成equals() {{则不会成为持久性的一部分1}}用于类。老学校但工作得很好,app运行得恰到好处。

<强> Incedent.groovy

hashCode()

<强> State.groovy

import groovy.transform.EqualsAndHashCode

@EqualsAndHashCode
class Incedent implements Serializable{
    Vehicle vehicle
    static embedded = ['vehicle']

    class Vehicle{
        State state
    }
}

根据上述内容,您将获得import groovy.transform.EqualsAndHashCode @EqualsAndHashCode class State implements Serializable { String name } 中的一列,用于嵌入数据类型为VARBINARY(在内存H2 db中进行测试时)。我希望在Incedent

中将stateName作为字符串

enter image description here