hibernate插入实体类数据库默认值不生效的问题

Posted pm97

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate插入实体类数据库默认值不生效的问题相关的知识,希望对你有一定的参考价值。

第一个问题老生常谈 

如果表结构设置默认值 数据库实体类不对该字段进行复制的情况下插入数据记录 字段直接以数据库设置的默认值进行插入
hibernate本身可以根据XML配置进行生效此配置

 1 <hibernate-mapping
 2     package="*.entity">
 3     <class name="ProEntity" table="PRODUCTINFO" dynamic-insert="true" dynamic-update="true" >               
 4                 <id name="proID" column="ID">
 5                         <generator class="assigned"></generator>
 6                 </id>            
 7         <property name="proCode" column="CODE"/>
 8         <property name="proName" column="Name"/>
 9         <property name="proDescription" column="DESCRIPTION" not-null="true"/>
10         <property name="proAmount" column="AMOUNT" not-null="true"/>
11         <property name="proManagerID" column="MANAGERID" not-null="true"/>
12         <property name="proManagerName" column="MANAGERNAME" not-null="true"/>
13     </class>
14 </hibernate-mapping>

我呸 现在已经9102年了 还在用配置文件但是依然附上对应的一些常用注解 虽然我也是抄的

 Hibernate允许我们在映射文件里控制insert和update语句的内容.比如在映射文件中<property 元素中的update属性设置成为false,那么这个字段,将不被包括在基本的update语句中,修改的时候,将不包括这个字段了.insert同理.dynamic动态SQL语句的配置也是很常用的.下面介绍配置SQL语句的具体属性:
1)<property元素 insert属性:设置为false,在insert语句中不包含这个字段,表示永远不会被插入,默认true
2)<property元素 update属性:设置为false,在update语句中不包含这个字段,表示永远不会被修改,默认true
3)<class元素 mutable属性:设置为false就是把所有的<property元素的update属性设置为了false,说明这个对象不会被更新,默认true
4)<property元素 dynamic-insert属性:设置为true,表示insert对象的时候,生成动态的insert语句,如果这个字段的值是null就不会加入到insert语句当中.默认false
5)<property元素 dynamic-update属性,设置为true,表示update对象的时候,生成动态的update语句,如果这个字段的值是null就不会被加入到update语句中,默认false
6)<class元素 dynamic-insert属性:设置为true,表示把所有的<property元素的dynamic-insert属性设置为true,默认false
7)<class元素 dynamic-update属性:设置为true,表示把所有的<property元素的dynamic-update属性设置为true,默认false

---------------------------------------------分割线-------------------------------------------------------------------

Hibernate生成动态SQL语句的消耗的系统资源(比如CPU,内存等)是很小的,所以不会影响到系统的性能,如果表中包含N多字段,建议把dynamic-update属性和insert属性设置为true,这样在插入和修改数据的时候,语句中只包括要插入或者修改的字段.可以节省SQL语句的执行时间,提高程序的运行效率. 
1、注解DynamicInsert
2、@Column(name = "Email",columnDefinition="varchar(128) not null")
LZ两个方法都使用了一下 明确看到的时 第二种未生效 所以不能做过多的说明 只能引用其他大佬们的实验结果 下边是https://blog.csdn.net/wzh577/article/details/97933549的可以借鉴 或者有兴趣的可以研究下

第一种LZ实验结果如下

@Test
public void addA()
ActivityTools ac= new ActivityTools();
activityToolsDao.save(ac);
/**
* 未增加注解的情况下数据库语句如下
* insert into activity_tools (activity_id, customized, enterprise_id, finishNumber, products, solutions_id, sumNumber, tools_id, toolsWeight, toolsNorm_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
* 增加注解后数据库插入语句如下
* insert into activity_tools values ()
*/

/**
* @Entity
* @Table(name = "activity_tools")
* @DynamicInsert
*/

  


实体类注解如下@DynamicInsert和@DynamicUpdate 两个注解的效果类似
因为LZ只需要使用到动态插入 动态修改的没有做实验 不过大致的翻阅了一些资料可以看到 但是因为更改的数据涉及到作用域的问题 其实对于更新来说第一步是查询 第二步是更新 第三步是插入
如果这三步 不能保证在同一个session下进行会导致脏数据的产生 因此 @DynamicUpdate 一般都会和@selectBeforeUpdate(true)一起进行使用,这个属性表示当我们在进行更新操作时,会先去数据库中查找这个实体对象的数据,这样就保存了当我们在进行更新操作时,查找后更新始终都在同一个session当中。
另外一种办法是hibernate提供的meger方法
merge方法的作用:
new一个对象并设置ID时,这个对象会被当作游离态处理,在使用merge时,如果在数据库中不能能找到这条记录,则使用insert将数据插入;如果在数据库中找到这条记录,则使用update将数据更新。
new一个对象没有设置ID时,这个对象会被当作瞬态处理,在使用merge时会根据实体类的主键生成策略保存这条数据。
使用merge存储到数据库的对象,其本身不会转变为持久态对象。

 

以上是关于hibernate插入实体类数据库默认值不生效的问题的主要内容,如果未能解决你的问题,请参考以下文章

在 Hibernate 中设置属性的默认值不起作用

hibernate映射实体类查询时数据库空字段赋值给实体类报错的问题

rails add_column 具有默认值但默认值不生效

hibernate中 session.save(实体类)方法的原理

Hibernate - 第一个 Sql 插入需要很长时间

Hibernate注解实体类