hibernate根据映射文件和实体类生成数据表时,无法生成关系表.
小弟现在做的项目需要使用hibernate根据映射文件和实体类生成数据表,但是使用过程中出现问题如下:
1: 映射文件加入映射关系后 dc_index_category_relation表无法正常生成.
2: 服务器启动时log日志:ERROR[main] 2012-07-06 19:10:57 org.hibernate.tool.hbm2ddl.SchemaUpdate > Unsuccessful: create table dc_index_category_relation (id int not null, index_id int null, index_category_id int identity not null, primary key (index_category_id, index_id))
ERROR[main] 2012-07-06 19:10:57 org.hibernate.tool.hbm2ddl.SchemaUpdate > 无法在表 'dc_index_category_relation' 中可为 Null 的列上定义 PRIMARY KEY 约束。
3:注释掉两个hbm映射文件中的set元素即映射关系就可以正常生成表.
求各位路过的前辈指点,该如何修改才能正常生成. 代码有点多,还望见谅.
说直接在数据库建表的朋友就不用了.. 因项目需要这方法行不通.
代码: IndexContext是指标 IndexCategory是指标自定义分类 IndexCategoryRelation是指标与分类关系
指标<多对多>分类
- Java code
// IndexCategory实体类public class IndexCategory { private int id; private int parentId;// 父分类id private String indexCategoryName;// 分类名称 private int userId; [color=#FF0000]private Set<IndexContext> indexes = new HashSet<IndexContext>();//与指标的关系 private Set<IndexCategory> subCats=new HashSet<IndexCategory>();//与本身的关系 子分类[/color]//getter and setter...}- Java code
//IndexCategoryRelation实体类public class IndexCategoryRelation { private int id; private int indexId;//指标id private int indexCategoryId;//分类id//getter and setter...}- Java code
//IndexCotext实体类public class IndexContext { private int id;//主键 private String pubDateCol;//公布日期字段名 private String dataSet;//表名 private boolean isValue;//是否为值字段,默认为F,此记录为指标值,为T时此记录为值,需要生成SQL语句 private String SQL;//"值记录,可以直接用:“select+""tableValue""+""from""+ dataSet +where+ """"指标记录: 字段名=值,如:country_id=30级父节点无此设置" private String name;//字段显示名,可供用户修改,默认为:isValue为T为字段名的中文,为F为指标的值(ID)的中文 private String tableValue;//字段实际值,parentID=0时为空;isValue为T为字段名,为F为指标的值(ID) private boolean ishidden;//默认False,是否隐藏 private String Backup1;//备份 private String Backup2;//备份 private int classID;//记录分类的记录ID,如果没被分类,则为0 private String updateDate;//更新日期列名 private Integer tableId;//数据集id private Double order;//排序 private String freqList;//变频条件 private String newfreq;//变频之后的频率 private Integer rootClassId;//记录根分类的ID private String indexFreq;//指标增加频率 private String indexUnit;//指标增加单位 private String indexSource;//指标增加来源 private Date saveIndexDate;//保存指标时间 private Date updateIndexDate;//更新指标时间 private String startPubDate;//开始公布日期 private String endPubDate;//最后公布日期 private Date endDataUpdate;//数据最后更新时间 private Boolean edited;//标记指标值是否被修改过 [color=#FF0000] private Set<IndexCategory> cats = new HashSet<IndexCategory>();//与自定义指标分类的关系[/color]//getter and setter...- XML code
<!-- 自定义指标分类 --> <class name="com.richeninfo.anaplatform.etl.hbean.IndexCategory" table="dc_index_category"> <id column="id" name="id" type="java.lang.Integer"> <generator class="native"/> </id> <property column="parent_id" name="parentId" type="java.lang.Integer"/> <property column="user_id" name="userId" type="java.lang.Integer"/> <property column="index_category_name" name="indexCategoryName" type="java.lang.String"/> <set name="indexes" table="dc_index_category_relation" inverse="true" lazy="false" fetch="join" cascade="all"> <key column="index_category_id" /> <many-to-many column="index_id" class="com.richeninfo.anaplatform.dbmgr.hbean.IndexContext" /> </set> <set name="subCats" cascade="all" inverse="true" lazy="false" fetch="join"> <key column="parent_id"></key> <one-to-many class="com.richeninfo.anaplatform.etl.hbean.IndexCategory"/> </set> </class> <!-- 自定义指标分类与指标关系--> <class name="com.richeninfo.anaplatform.etl.hbean.IndexCategoryRelation" table="dc_index_category_relation"> <id column="id" name="id" type="java.lang.Integer"> <generator class="native"/> </id> <property column="index_id" name="indexId" type="java.lang.Integer"/> <property column="index_category_id" name="indexCategoryId" type="java.lang.Integer"/> </class><!--指标--> <class lazy="false" name="com.richeninfo.anaplatform.dbmgr.hbean.IndexContext" table="dc_index_context"> <meta attribute="use-in-tostring">true</meta> <id column="id" name="id" type="java.lang.Integer"> <generator class="native"/> </id> <!--中间N多字段我就不拷贝了,免得大家晃眼--> <set name="cats" table="dc_index_category_relation"> <key column="index_id" /> <many-to-many column="index_category_id" class="com.richeninfo.anaplatform.etl.hbean.IndexCategory" /> </set> </class>
- XML code
<!--applicationContext-database.xml--><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" default-autowire="byName"> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="mySessionFactory" /> </bean> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>/WEB-INF/classes/conf/database.properties</value> <value>/WEB-INF/classes/conf/log4database.properties</value> </list> </property> </bean> <bean id="mySessionFactory" name="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" autowire="no"> <property name="dataSource" ref="myDataSource" /> <property name="mappingLocations"> <list> <value>classpath:conf/*/*hbean.hbm.xml</value> <!-- <value>classpath:conf/*/*hbean.oracle.hbm.xml</value> --> </list> </property> <property name="lobHandler" ref="lobHandler" /> <property name="hibernateProperties"> <value> hibernate.dialect=${database.dialect} hibernate.cache.use_query_cache=false hibernate.cache.use_second_level_cache=false hibernate.hbm2ddl.auto=update <!--MySQLDialect SQLServerDialect hibernate.show_sql=true hibernate.format_sql=true --> </value> </property> </bean> <bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true" /> <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${database.driver}" /> <property name="url" value="${database.url}" /> <property name="username" value="${database.username}" /> <property name="password" value="${database.password}" /> </bean> <bean id="logDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${log4j.driver}"></property> <property name="url" value="${log4j.url}"></property> <property name="username" value="${log4j.username}"></property> <property name="password" value="${log4j.password}"></property> </bean> <!-- hibernate.hbm2ddl.auto=update --> <bean id="logSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" autowire="no"> <property name="dataSource" ref="logDataSource" /> <property name="mappingResources"> <list> <value>conf/common/actionlog_hbean.hbm.xml</value> </list> </property> <property name="lobHandler" ref="lobHandler" /> <property name="hibernateProperties"> <value>hibernate.dialect=org.hibernate.dialect.SQLServerDialect</value> </property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"> <ref bean="myDataSource" /> </property> </bean> <bean id="dataCenterSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" autowire="no"> <property name="dataSource" ref="dataCenterSource" /> <property name="mappingLocations"> <list> <value>classpath:conf/*/*datacenter.hbm.xml</value> </list> </property> <property name="lobHandler" ref="lobHandler" /> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.SQLServerDialect hibernate.cache.use_query_cache=false hibernate.cache.use_second_level_cache=false hibernate.hbm2ddl.auto=update </value> </property> </bean> <bean id="dataCenterSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${datacenterdatabase.driver}" /> <property name="url" value="${datacenterdatabase.url}" /> <property name="username" value="${datacenterdatabase.username}" /> <property name="password" value="${datacenterdatabase.password}" /> </bean></beans>
[解决办法]
index_id这个字段可以为空,不能设为主键。设为主键的字段不允许为空哦。。。
[解决办法]
<id column="id" name="id" type="java.lang.Integer">
<generator class="native"/>
</id>
改成<id column="id" name="id" type="java.lang.Integer">
<generator class="assign"/>
</id>,然后每次添加时手动指定id号