JpaRepository не сохраняет сущность - PullRequest
1 голос
/ 12 октября 2019

У меня есть сервер, использующий пружинную загрузку и данные весны jpa.

У меня есть два класса с пометкой @RestController на моем сервере. Один из них может изменить сущности, а другой - нет.

@RestController
@Slf4j
public class ControllerA {
    private EntityRepository entityRepository;

    public ControllerA(EntityRepository entityRepository) {
        this.entityRepository = entityRepository;
    }

    @PostMapping("/pathStr")
    public void changeEntity(@RequestParam("entityId") Long entityId) {
        // init
        Entity entity = entityRepository.findById(entityId);
        // make changes to entity
        entity.getOneToOneLinkedEntity().setIntProperty(0);
        // save entity
        entityRepository.save(entity);
    }
}

@RestController
@Slf4j
public class ControllerB {

    private Entity cachedEntity;
    private EntityRepository entityRepository;

    public ControllerB(EntityRepository entityRepository) {
        this.entityRepository = entityRepository;
    }

    @MessageMapping("/otherPath")
    public void getEntity(ArgumentType argument) {
        if (cachedEntity == null) {
            cachedEntity = entityRepository.save(new Entity());
        }
        Entity entity = entityRepository.findById(cachedEntity.getId()).orElse(null);
        int properyValue = entity.getOneToOneLinkedEntity().getIntProperty(); // this is not zero
    }
}

Вот две сущности и хранилище:

@Entity
public class Entity implements Serializable {

    @Id
    @GeneratedValue private Long id;

    @NotNull
    @OneToOne(cascade=CascadeType.ALL)
    private OneToOneLinkedEntity linkedEntity;
}

@Entity
public class OneToOneLinkedEntity implements Serializable {

    @Id
    @GeneratedValue private Long id;

    @NotNull
    private int intProperty = 0;
}

public interface EntityRepository extends JpaRepository<Entity, Long> {
}

Я звоню в ControllerA.changeEntity изклиент, и как только это возвращается, я делаю еще один вызов ControllerB.getEntity. Изменения, которые я сделал в первом вызове, не отображаются во втором вызове ( и их нет в базе данных, если я запрашиваю напрямую с помощью sql ), свойство int имеет старое значение. Даже если я выполняю сохранение только в Entity, а не в relatedEntity, CascadeType.ALL также должен обновить связанное сущность, верно?

Я попытался добавить entityRepository.flush() после сохранения в ControllerA,но проблема все еще появляется. Что я могу сделать? Как я могу заставить ControllerB получить правильное значение intProperty?

Это то, что я имею в application.properties:

spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost:3306/db_name
spring.datasource.username=user
spring.datasource.password=pass
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultComponentSafeNamingStrategy

Ответы [ 2 ]

0 голосов
/ 13 октября 2019

Вы игнорируете внедрение зависимостей, которое является прелестью Spring Framework.

  1. Создайте класс Repository, который реализует JPARepository, и аннотируйте его с помощью @Repository.
  2. Создайте класс Service и аннотируйте его с помощью @Service и @ Transactional.
  3. В классе Service выполните автоматическое связывание Repository и вызовите соответствующие методы, например .save () .find () и т. Д.
  4. В Controller Class autowire класс сервиса и метод вызова сервиса, который будет вызывать методы репозитория.

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

0 голосов
/ 12 октября 2019

Вы должны добавить аннотацию @Transactional в свой метод, чтобы Spring обработал транзакцию и зафиксировал ваши изменения.
Обычно это относится к классу @Service, но в вашем примере я вижу, что у вас его нет. так что поставьте его на контроллер (или добавьте сервисный слой, я думаю, что лучше)

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