简体   繁体   English

当数据不持久化时,convertToDatabaseColumn?

[英]convertToDatabaseColumn when data is not being persisted?

I have implemented method AttributeConverter.convertToEntityAttribute to load json data from the db. 我已经实现了AttributeConverter.convertToEntityAttribute方法来从数据库加载json数据。 I am not trying to persist data, but for some reason convertToDatabaseColumn is being called. 我没有尝试保留数据,但是由于某种原因,正在调用convertToDatabaseColumn

This is what happens: 这是发生了什么:
1. I call a repository method 1.我调用存储库方法
2. then a call to AttributeConverter.convertToEntityAttribute follows -> returns a list of entity Cx . 2.然后对AttributeConverter.convertToEntityAttribute的调用->返回实体Cx的列表 Till this point everything is normal. 至此,一切正常。
3. But for some reason AttributeConverter.convertToDatabaseColumn is called right after, with that same list of entity Cx as argument -> returns stringV 3.但是由于某种原因, 紧随其后调用了AttributeConverter.convertToDatabaseColumn,使用相同的实体Cx列表作为参数->返回stringV
4.Now convertToEntityAttribute is called again with stringV as argument, which is also strange. 4.现在,再次以stringV作为参数调用convertToEntityAttribute,这也很奇怪。

Could it be that a @OneToOne relation is causing this? 可能是@OneToOne关系引起的吗? Why is this executing convertToDatabaseColumn if I'm not persisting an entity, at least explicitly? 如果我没有至少持久地保留实体,为什么要执行convertToDatabaseColumn?

All of this happens just by calling a single method in one of my repository classes: 所有这些仅通过在我的一个存储库类中调用一个方法即可实现:

Here is the code 这是代码

public interface RSTRepository extends CrudRepository<RST, Long> {

    List<RST> findByDuctNameIgnoreCase(String ductName);
}

@Entity
@Table(name="r_s_t")
public class RST {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @OneToOne
    @JoinColumn(name = "r_s_id")
    private Rs rs;

    @Column(name = "channel")
    private String channelName;
    ...
}

@Entity
@Table(name="r_s")
public class RS {
    @Id
    @Column(name = "rs_id", columnDefinition = "json")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(name = "c_x", columnDefinition = "json")
    @Convert(converter = JsonToCxConverter.class)
    private List<Cx> cxs;
    ...
 }

public class Cx {
    private Long someId;
    private List<Long> values;
...    
}
@Converter
public class JsonToCxConverterimplements AttributeConverter<List<Cx>, String>{

   //this gets executed
    @Override
    public String convertToDatabaseColumn(List<Cx> entityAttribute) {
        ObjectMapper objectMapper = new ObjectMapper();
        log.info("--------------------");
        return "";
    }

    @Override
    public List<Cs> convertToEntityAttribute(String dbData) {

   if (dbData == null || dbData.isEmpty()) return Collections.emptyList();
   //... uses the object mapper to parse the json and return a simple object.

   ...

} }

Like I said, this happens when calling RSTRepository.findByDuctNameIgnoreCase 就像我说的那样,这在调用RSTRepository.findByDuctNameIgnoreCase时发生

Yes its really behaving like you are saying. 是的,它的行为确实像您说的那样。 Also when persisting RST, Converter is also called 3x. 同样,在保留RST时,Converter也称为3x。

It also called 3x when reading just RS entity, ie it is not caused by @OneToOne relation. 仅读取RS实体时,它也称为3x,即不是由@OneToOne关系引起的。

I think it is how hibernate works. 我认为这是冬眠的方式。 It should not be a problem, you get the right data without error. 没问题,您将获得正确的数据而不会出错。

From stacktrace I see that second and third call is from AbstractRowReader.performTwoPhaseLoad(). 从stacktrace中,我看到第二个和第三个调用来自AbstractRowReader.performTwoPhaseLoad()。

at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.performTwoPhaseLoad(AbstractRowReader.java:241)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:209)
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:133)

I think its something that cannot be disabled. 我认为这是不能禁用的。 From hibernate sources I see that entity is registered to "hydrating". 从休眠源中,我看到该实体已注册为“水合”。 I found more about it here https://stackoverflow.com/a/29538797/2044957 我在这里找到了更多有关它的信息https://stackoverflow.com/a/29538797/2044957

Another thing: This is happening only when using converter on a collection. 另一件事:仅当在集合上使用转换器时,才会发生这种情况。 Converter is called once if it used on single type, for example AttributeConverter<String, String> . 如果Converter用于单一类型,例如AttributeConverter<String, String> ,则调用一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM