我是Hibernate的新手,从MyBatis迁移。 我有这个Customer bean,我正在尝试使用xml映射保存(INSERT)。这是我的代码的较短版本:
豆类:
public class Customer {
private Integer id;
private String code;
private SystemObject systemObject = new SystemObject();
}
public class SystemObject {
private Integer objectId;
private Integer userIdCreate;
private Integer userIdUpdate;
private Date createDate;
private Date updateDate;
private Workspace workspace = new Workspace();
}
public class Workspace {
private Integer id;
private String code;
private String name;
}
如您所见,Customer有一个SystemObject。 SystemObject是一个通用对象,代码中的所有bean都有一个。 SystemObject有一个工作区。
问题是,表CUSTOMER,对OBJECT的引用,以及对WORKSPACE 的引用。在“objects world”中,我通过执行getSystemObject()。getWorkspace()。getId()来获取工作区id,但我不知道如何在Hibernate中执行此操作
表(目前在PostgreSQL上):
create table CUSTOMER (
CUSTOMER_ID INT4 not null,
OBJECT_ID INT4 not null,
WORKSPACE_ID INT4 not null,
CODE VARCHAR(100) not null,
constraint PK_CUSTOMER primary key (CUSTOMER_ID),
constraint AK_CUS_CODE unique (WORKSPACE_ID, CODE)
);
create table OBJECT (
OBJECT_ID INT4 not null,
WORKSPACE_ID INT4 not null,
USER_ID_CREATE INT4 not null,
USER_ID_UPDATE INT4 not null,
CREATE_DATE DATE not null,
UPDATE_DATE DATE not null,
constraint PK_OBJECT primary key (OBJECT_ID)
);
create table WORKSPACE (
WORKSPACE_ID INT4 not null,
CODE VARCHAR(100) not null,
NAME VARCHAR(100) not null,
constraint PK_WORKSPACE primary key (WORKSPACE_ID),
constraint AK_WS_CODE unique (CODE)
);
alter table CUSTOMER
add constraint FK_CUS_OBJ foreign key (OBJECT_ID)
references OBJECT (OBJECT_ID)
on delete restrict on update restrict;
alter table CUSTOMER
add constraint FK_CUS_WS foreign key (WORKSPACE_ID)
references WORKSPACE (WORKSPACE_ID)
on delete restrict on update restrict;
alter table OBJECT
add constraint FK_OBJ_WS foreign key (WORKSPACE_ID)
references WORKSPACE (WORKSPACE_ID)
on delete restrict on update restrict;
而且,这是我对Customer对象的映射:
<class name="ar.com.portal.bean.Customer" table="CUSTOMER">
<id name="id" column="CUSTOMER_ID" >
<generator class="increment"></generator>
</id>
<property name="code" column="CODE" />
<many-to-one name="systemObject" class="ar.com.framework.base.SystemObject" column="OBJECT_ID"
unique="true" not-null="true" lazy="false" cascade="all" ></many-to-one>
</class>
主要代码:
Session session = HibernateSessionManager.getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
Customer anew = new Customer();
anew.setCode("new test");
SystemObjectManager.prepareSystemObject(anew); //this line sets all values for the systemObject inside Customer
anew.getSystemObject().getWorkspace().setId(1);
session.save(anew);
transaction.commit();
这样,hibernate尝试插入两个对象Customer和SystemObject,但是因为Customer在WORKSPACE_ID列中为null而失败:
(对不起,错误是西班牙语)
Caused by: org.postgresql.util.PSQLException: ERROR: el valor null para la columna «workspace_id» viola la restricción not null Detail: La fila que falla contiene (3, 8, null, 'new test').
然后,我尝试了这种方式。在SystemObject中添加了一个getWorkspaceId()(只是为了尝试简化一步)并将映射更改为:
<class name="ar.com.portal.bean.Customer" table="CUSTOMER">
<id name="id" column="CUSTOMER_ID" >
<generator class="increment"></generator>
</id>
<property name="code" column="CODE" />
<component name="systemObject" class="ar.com.framework.base.SystemObject" >
<property name="workspaceId" column="WORKSPACE_ID" />
</component>
<many-to-one name="systemObject" class="ar.com.framework.base.SystemObject" column="OBJECT_ID"
unique="true" not-null="true" lazy="false" cascade="all" ></many-to-one>
</class>
甚至没有开始:
Caused by: org.hibernate.MappingException: Duplicate property mapping of systemObject found in ar.com.portal.bean.Customer
但我知道这可行,因为如果删除“多对一”,则INSERT语句中存在WORKSPACE_ID列的值(但没有OBJECT_ID则失败)
所以...我有这个属性,我需要它同时是一个多对一的关系和组件,但Hibernate不喜欢这样。还有另一种方法可以解决这种特殊情况吗?或者我要使用命名查询编写自定义插入?
答案 0 :(得分:0)
bean应该是
public class Customer {
private Integer id;
private String code;
private SystemObject systemObject = new SystemObject();
private Workspace workspace= new Workspace ();
}
然后映射应该是
<class name="ar.com.portal.bean.Customer" table="CUSTOMER">
<id name="id" column="CUSTOMER_ID" >
<generator class="increment"></generator>
</id>
<property name="code" column="CODE" />
<component name="workspace" class="ar.com.framework.base.Workspace" >
<property name="workspaceId" column="WORKSPACE_ID" />
</component>
<many-to-one name="systemObject" class="ar.com.framework.base.SystemObject" column="OBJECT_ID"
unique="true" not-null="true" lazy="false" cascade="all" ></many-to-one>
</class>