hibernate惰性属性加载使用@dynamicupdate进行假阳性字段检测

sbdsn5lh  于 2021-07-13  发布在  Java
关注(0)|答案(0)|浏览(230)

我有一个具有lazy属性的hibernate实体。

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Entity
@Table(name = "rule", schema = "mariott_rule")
@DynamicUpdate // this is important
public class Rule {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "rule_id")
    private Long id;

    @Column(name = "switch")
    private boolean switched;

    @Column(name = "rule_name")
    private String name;

    private String description;

    @Column(name = "date_update")
    private ZonedDateTime dateUpdated;

    @Column(name = "param_values", columnDefinition = "text")
    @Convert(converter = RuleParamValuesAttributeConverter.class)
    @Basic(fetch = LAZY)
    private RuleParamValuesValidatedEntity paramValues;
}

我有两种方法可以关闭或打开规则。在打开规则之前,我们必须确保 paramValues 是有效的。这就是为什么我们用一个单独的查询来获取它们。但对于反之亦然的操作来说,这并不重要。所以, paramValues 在这种情况下不加载。
但奇怪的部分来了。打开操作生成预期的sql。

validateParamValues(rule.getParamValues());
ruleRepository.saveAndFlush(
    rule.asBuilder()
        .switched(true)
        .dateUpdated(now)
        .build();
);
update mariott_rule.rule set date_update=?, switch=? where rule_id=?

同时,关闭操作增加了 paramValues 生成sql并将其值赋给 "null" (的字符串值) null 文字)。

// NO param values fetching
ruleRepository.saveAndFlush(
    rule.asBuilder()
        .switched(false)
        .dateUpdated(now)
        .build();
);
update mariott_rule.rule set date_update=?, param_values=?, switch=? where rule_id=?
binding parameter [1] as [TIMESTAMP] - [2021-04-09T08:10:28.423406Z]
binding parameter [2] as [VARCHAR] - [null]
binding parameter [3] as [BOOLEAN] - [false]
binding parameter [4] as [BIGINT] - [1]

也许是因为 RuleParamsValuesAttributeConverter.class .
我移除了 Basic(fetch = LAZY) . 虽然有帮助,但那不是我想要的。有什么想法吗?
p、 顺便说一句,当我离开的时候 Basic(fetch = LAZY) 看来 @DynamicUpdate 我也停下来工作了。
编辑:
这是你的名字 JsonAttributeConverter 以及 RuleParamValuesAttributeConverter ```
@Slf4j
@RequiredArgsConstructor
public abstract class JsonAttributeConverter implements AttributeConverter<A, String> {
private final ObjectMapper objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
private final Class entityClass;
private final String dbColumnName;
private final A defaultValue;

@Override
public String convertToDatabaseColumn(A attribute) {
    try {
        return objectMapper.writeValueAsString(attribute);
    } catch (Exception e) {
        throw new ConvertException(String.format("Cannot convert %s to string", entityClass.getSimpleName()), e);
    }
}

@Override
public A convertToEntityAttribute(String dbData) {
    try {
        return objectMapper.readValue(dbData, entityClass);
    } catch (Exception e) {
        if (log.isDebugEnabled()) {
            log.warn(
                String.format(
                    "Cannot convert database column %s to the %s. The default value shall be used",
                    dbColumnName,
                    entityClass.getSimpleName()),
                e
            );
        }
        return defaultValue;
    }
}

}

@Converter
public class RuleParamValuesAttributeConverter extends JsonAttributeConverter {
public RuleParamValuesAttributeConverter() {
super(RuleParamValuesValidatedEntity.class, "mariott_rule.rule.param_values", RuleParamValuesValidatedEntity.getInvalidInstance());
}
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题