convertToDatabaseColumn, когда данные не сохраняются? - PullRequest
0 голосов
/ 15 марта 2019

Я реализовал метод AttributeConverter.convertToEntityAttribute для загрузки данных JSON из БД. Я не пытаюсь сохранить данные, но по какой-то причине вызывается convertToDatabaseColumn .

Вот что происходит:
1. Я вызываю метод репозитория
2. затем следует вызов AttributeConverter.convertToEntityAttribute -> возвращает список сущностей Cx . До этого момента все нормально.
3. Но по какой-то причине AttributeConverter.convertToDatabaseColumn вызывается сразу после того, как тот же список сущности Cx в качестве аргумента -> возвращает stringV
4. Теперь атрибут convertToEntityAttribute вызывается снова с stringV в качестве аргумента, что также странно.

Может быть, это связано с отношением @OneToOne? Почему это выполняет convertToDatabaseColumn, если я не сохраняю сущность, по крайней мере, явно?

Все это происходит просто путем вызова одного метода в одном из моих классов репозитория:

Вот код

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.

   ...
* *} Тысяча двадцать-один

Как я уже сказал, это происходит при вызове RSTRepository.findByDuctNameIgnoreCase

1 Ответ

1 голос
/ 15 марта 2019

Да, он действительно ведет себя так, как вы говорите. Также при сохранении RST конвертер также называется 3x.

Он также вызывается 3x при чтении только сущности RS, т. Е. Не вызвано отношением @OneToOne.

Я думаю, что так работает гибернация. Это не должно быть проблемой, вы получите правильные данные без ошибок.

Из стека трассировки я вижу, что второй и третий вызовы сделаны из 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)

Я думаю, это то, что нельзя отключить. Из спящих источников я вижу, что сущность зарегистрирована как «увлажняющая». Я нашел больше об этом здесь https://stackoverflow.com/a/29538797/2044957

Другое дело: это происходит только при использовании конвертера в коллекции. Конвертер вызывается один раз, если он используется для одного типа, например AttributeConverter<String, String>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...