hibernate根据映射文件和实体类生成数据表时,无法生成关系表.

时间:2021-09-21 22:17:37
小弟现在做的项目需要使用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是指标与分类关系
指标<多对多>分类
  



// IndexCategory实体类

public class IndexCategory {

private int id;
private int parentId;// 父分类id
private String indexCategoryName;// 分类名称
private int userId;
private Set<IndexContext> indexes = new HashSet<IndexContext>();//与指标的关系
private Set<IndexCategory> subCats=new HashSet<IndexCategory>();//与本身的关系 子分类

//getter and setter...
}



//IndexCategoryRelation实体类

public class IndexCategoryRelation {

private int id;
private int indexId;//指标id
private int indexCategoryId;//分类id
//getter and setter...
}



//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;//标记指标值是否被修改过
    private Set<IndexCategory> cats = new HashSet<IndexCategory>();//与自定义指标分类的关系
//getter and setter...





  <!-- 自定义指标分类 -->
   <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>



<!--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>

11 个解决方案

#1


index_id这个字段可以为空,不能设为主键。设为主键的字段不允许为空哦。。。

#2


给index_id的get方法,设个不能为空的注解试试。

#3


引用 1 楼  的回复:
index_id这个字段可以为空,不能设为主键。设为主键的字段不允许为空哦。。。



 <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" not-null="true"/>
    <property column="index_category_id" name="indexCategoryId" type="java.lang.Integer" not-null="true"/>
  </class>


我试过这样加非空约束 但是没用, 因为我生成表的方式不是使用注解所以没试过注解加约束(而且也没用过- -) 不过应该是同理的吧 大哥还有别的解决方案吗?

#4



<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" not-null="true"/>
    <property column="index_category_id" name="indexCategoryId" type="java.lang.Integer" not-null="true"/>
  </class>

源码不能加颜色.. 再发一次.

#5


没有前辈们路过指点一下吗?

#6


引用 5 楼  的回复:
没有前辈们路过指点一下吗?


看 文 档

#7


<property column="index_category_id" name="indexCategoryId" type="java.lang.Integer" not-null="true"/>
改成下面试试
<property name="indexCategoryId" type="java.lang.Integer">
  <column name="index_category_id" not-null="true"/>
</property>

<property name="index_category_id" not-null="true"/>

#8


<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号

#9


引用 7 楼  的回复:
<property column="index_category_id" name="indexCategoryId" type="java.lang.Integer" not-null="true"/>
改成下面试试
<property name="indexCategoryId" type="java.lang.Integer">
  <column name="index_categ……



这种写法不是一样吗

#10


引用 2 楼  的回复:
给index_id的get方法,设个不能为空的注解试试。


可是我的映射文件并没有将index_id字段设置为主键啊.. 这个是最纠结的.

#11


其实这个功能已经做好了.我当时是先不加映射关系正常生成的表 然后实现功能.
之后开发和调试都正常. 级联操作也都正常.
但是后来发布的时候发现服务器根据映射文件生成表的时候 关系表无法生成.
因为项目的适用方和其他一些原因 直接在数据库建表是不可行的.
找来找去也找不到原因啊. 添加非空约束也试过了 都不行.
真心请求路过的前辈们指点一二啊..

#1


index_id这个字段可以为空,不能设为主键。设为主键的字段不允许为空哦。。。

#2


给index_id的get方法,设个不能为空的注解试试。

#3


引用 1 楼  的回复:
index_id这个字段可以为空,不能设为主键。设为主键的字段不允许为空哦。。。



 <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" not-null="true"/>
    <property column="index_category_id" name="indexCategoryId" type="java.lang.Integer" not-null="true"/>
  </class>


我试过这样加非空约束 但是没用, 因为我生成表的方式不是使用注解所以没试过注解加约束(而且也没用过- -) 不过应该是同理的吧 大哥还有别的解决方案吗?

#4



<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" not-null="true"/>
    <property column="index_category_id" name="indexCategoryId" type="java.lang.Integer" not-null="true"/>
  </class>

源码不能加颜色.. 再发一次.

#5


没有前辈们路过指点一下吗?

#6


引用 5 楼  的回复:
没有前辈们路过指点一下吗?


看 文 档

#7


<property column="index_category_id" name="indexCategoryId" type="java.lang.Integer" not-null="true"/>
改成下面试试
<property name="indexCategoryId" type="java.lang.Integer">
  <column name="index_category_id" not-null="true"/>
</property>

<property name="index_category_id" not-null="true"/>

#8


<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号

#9


引用 7 楼  的回复:
<property column="index_category_id" name="indexCategoryId" type="java.lang.Integer" not-null="true"/>
改成下面试试
<property name="indexCategoryId" type="java.lang.Integer">
  <column name="index_categ……



这种写法不是一样吗

#10


引用 2 楼  的回复:
给index_id的get方法,设个不能为空的注解试试。


可是我的映射文件并没有将index_id字段设置为主键啊.. 这个是最纠结的.

#11


其实这个功能已经做好了.我当时是先不加映射关系正常生成的表 然后实现功能.
之后开发和调试都正常. 级联操作也都正常.
但是后来发布的时候发现服务器根据映射文件生成表的时候 关系表无法生成.
因为项目的适用方和其他一些原因 直接在数据库建表是不可行的.
找来找去也找不到原因啊. 添加非空约束也试过了 都不行.
真心请求路过的前辈们指点一二啊..