Транзакционный метод JPA обновляет столбец после его сохранения

#java #mysql #hibernate #jpa #persistence

#java #mysql #спящий режим #jpa #постоянство

Вопрос:

Я сохраняю объект, который размещен в веб-сервисе REST, но пытаюсь обновить некоторые поля непосредственно перед этим. У меня есть класс A, который имеет B в качестве своего свойства (нет связи, просто сложность поля из-за того, что это поле является отдельным полем / объектом JSON). Я пытаюсь обновить свойство B до сохранения A, что на самом деле работает просто отлично.. ЗА исключением того, что он вставляет новый класс, он также обновляет поле. Что-то вроде этого:

 public class A {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
Long id;

@Lob
@Convert(converter = BConverter.class)
B b_field;
}

public class B {
List<String> someVals;
List<Map<String, String>> amts;
}






@Converter
public class BConverter implements AttributeConverter<B, String> {
    
    private final static ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    public String convertToDatabaseColumn(B b) {
        try {
            return objectMapper.writeValueAsString(b);
        } catch (JsonProcessingException ex) {....
            return null;
        }
    }
    
    @SneakyThrows
    @Override
    public B convertToEntityAttribute(String bVal) {
        try {
            return objectMapper.readValue(bVal, B.class);
        } catch (IOException ex) {
            ......
            return null;
        }
    }
}
  

Вот метод POST для сохранения:

 @Override
@Transactional
public A saveA(A a){
  List<Map<String, String>> amts= new ArrayList<>();
  amts.add(....here goes some hashmap...);
  a.getB_field.setAmts(amts);
  return repository.save(a);
}
  

Запущенные запросы:

 insert into A (id, b_field) -> here b_field already contains the added values from above
update A set b_field =? where id=?  -> same object that is already inserted. Basically useless
  

Я могу себе представить, что это связано с совершаемой транзакцией, но не понимаю, почему он не понимает, что никаких изменений нет. Есть идеи? Спасибо!!

Комментарии:

1. id Аннотировано ли поле @Id ? Отличается ли это, если это так?

2. да, это для класса A. Я обновлю аннотации в вопросах

3. Вы пробовали аннотировать id B с @Id помощью?

4. Идентификатор B не является идентификатором, это просто случайное поле. Я также могу изменить это в примере. B — это скорее структура, как я уже сказал, это удобно для столбца JSON

5.Вы пробовали hibernate-types проект от Влада Михалча? Смотрите: vladmihalcea.com/java-map-json-jpa-hibernate , может быть, это может как-то помочь.

Ответ №1:

Похоже, я сам приблизился к ответу, по крайней мере, на данный момент: это карта, которая прерывает поток. Когда дело доходит до Maps и JPA, есть особенности, но до сих пор ни один из них не работал для меня до сих пор в этом случае. Обходной путь: если я создаю класс с определенными полями вместо динамической карты, он отлично работает.
Обновить:
Вдохновленный ссылкой от @jccampanero, я изменил Map на JsonNode и динамически создаю узел с помощью JsonNodeFactory. Это работает как шарм!