我一直在尝试使用 @DynamicUpdate 实施实体更新。文档(http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/)说:
dynamicInsert / dynamicUpdate(默认为false):指定应在运行时生成INSERT / UPDATE SQL,仅包含值不为空的列。
但是我没有设法让它成功,所以我挖掘了AbstractEntityPersister的来源,看到了这个:
generateUpdateString( propsToUpdate, j, oldFields, j == 0 && rowId != null )
这是一种基于< propsToUpdate'生成SQL查询字符串的方法。这是从:
获得的布尔数组getPropertiesToUpdate( dirtyFields, hasDirtyCollection );
其中' dirtyFields'是一个整数数组的id'脏'列。
但无处可去
getPropertiesToUpdate(final int[] dirtyProperties, final boolean hasDirtyCollection)
我能够找到检查修改列是否为空的机制,所以即使我想要合并的实体有一些空字段,所有这些都在数据库中更新,用空值覆盖现有数据。
我的问题是:我的推理在哪里出错?
编辑:
这是我的代码,正如Chaitanya所要求的那样:
实体:
@SuppressWarnings("serial")
@Entity(name = "t_quiz_groups")
@DynamicUpdate
@SelectBeforeUpdate
public class QuizGroupEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "group_id")
private long id;
@Column(name = "description", nullable = false)
private String description;
@Column(name = "create_date", nullable = false)
@Column(name = "create_date")
private Calendar createDate;
+setters and getters
然后,我有一个服务(@Transactional)方法:
public void update(long groupId, String newDescription) throws ServiceException {
QuizGroupEntity quizGroupEntity = quizRepository.getGroupById(groupId);
ExpectedNotNull.of(quizGroupEntity, RegistryErrorCodes.QUIZ_GROUP_NOT_EXISTS);
quizGroupEntity.setCreateDate(null); //for testing purposes i am setting another
field as null (shouldnt be updated then, right?)
quizRepository.lock(quizGroupEntity, LockModeType.WRITE);
quizGroupEntity.updateDescription(newDescription); // new description
quizRepository.merge(quizGroupEntity);
}
现在,在AbstractEntityPersiste中,方法:
getPropertiesToUpdate( dirtyFields, hasDirtyCollection );
调用,dirtyFields []由两个“脏”组成。列:[0,2] - 这是正确的,这两列被修改(日期和描述,日期设置为null)
然后,调用generateUpdateString(propsToUpdate,j,oldFields,j == 0&& rowId!= null),其中包含了propsToUpdate'看起来像这样:
[true, false, true, false, true]
哪个错了,因为确实修改了第一列和第三列,但是第一列被设置为null,这就是为什么
generateUpdateString( propsToUpdate, j, oldFields, j == 0 && rowId != null )
生成查询:
[update t_quiz_groups set create_date=?, description=?, version=? where group_id=? and version=?]
这将修改create_date,并使用空值覆盖它。