Java Hibernate 4.3@DynamicUpdate真的不包含空值吗?
我一直在尝试使用@DynamicUpdate实现实体更新。文件说: dynamicInsert/DynamicCupDate默认值为false:指定应在运行时生成INSERT/UPDATE SQL,并且仅包含值不为null的列 但我没能让它工作,所以我深入研究了AbstractEntityPersister的源代码,发现:Java Hibernate 4.3@DynamicUpdate真的不包含空值吗?,java,hibernate,jpa,Java,Hibernate,Jpa,我一直在尝试使用@DynamicUpdate实现实体更新。文件说: dynamicInsert/DynamicCupDate默认值为false:指定应在运行时生成INSERT/UPDATE SQL,并且仅包含值不为null的列 但我没能让它工作,所以我深入研究了AbstractEntityPersister的源代码,发现: generateUpdateString( propsToUpdate, j, oldFields, j == 0 && rowId != null ) 它
generateUpdateString( propsToUpdate, j, oldFields, j == 0 && rowId != null )
它是一种基于“propsToUpdate”生成SQL查询字符串的方法,propsToUpdate是从以下位置获取的布尔数组:
getPropertiesToUpdate( dirtyFields, hasDirtyCollection );
其中“dirtyFields”是“dirty”列的id的整数数组
但在任何地方
getPropertiesToUpdate(final int[] dirtyProperties, final boolean hasDirtyCollection)
我能够找到检查修改后的列是否不为null的机制,所以即使我想要合并的实体有一些null字段,它们都会在数据库中更新,用null覆盖现有数据
我的问题是:我的推理哪里有错误
编辑:
这是我的密码,按照柴坦尼亚的要求:
实体:
@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
然后,我有一个service@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[]由两个“dirty”列组成:[0,2]-这是正确的,这两个列被修改为date和description,date设置为null
然后,生成更新字符串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,并用null值覆盖它。您可以添加您尝试过的代码吗?hibernate生成的查询是什么,证明dynamicInsert/DynamicCupDate没有按预期工作?我已经按照您的要求在我的问题中提供了一些代码。您好,我有类似的问题。我希望@DynamicUpdate能够避免尝试更新空字段。但Hibernate试图做到这一点。我创建实体,然后更新单个字段。Hibernate失败,因为NotNull属性引用了null或瞬时值,因为我没有在update中设置NotNull列。