【问题标题】:JpaRepository not saving entity [duplicate]JpaRepository 不保存实体 [重复]
【发布时间】:2019-10-12 19:31:39
【问题描述】:

我有一个使用 spring boot 和 spring data 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 属性具有旧值。即使我只在实体上而不是在linkedEntity上进行保存,CascadeType.ALL 也应该使链接实体更新,对吧?

我尝试在 ControllerA 中保存后添加entityRepository.flush(),但问题仍然存在。我能做些什么?如何让 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

【问题讨论】:

  • 带有级联的 OneToOne 注释应该足以完成这项工作。您能解释一下“cachedEntity”值的来源吗?
  • @Raphael 它是在第一次调用 ControllerB.getEntity() 时创建的。类似于:if (cachedEntity == null) {cachedEntity = entityRepository.save(new Entity());}。我将代码添加到问题中

标签: java spring-boot jpa spring-data-jpa spring-repositories


【解决方案1】:

您应该在您的方法中添加@Transactional 注释,以便spring 将处理事务并提交您的更改。
这通常出现在@Service类上,但我在你的例子中看到你没有,所以把它放在控制器上(或者添加服务层,我认为它更好)

【讨论】:

  • 我尝试将@Transactional添加到类和方法中,一个来自javax.transaction,一个来自org.springframework.transaction.annotation。调用changeEntity后还是看不到数据库的变化
  • 是否需要在 application.properties 中添加一些内容?
  • 尝试将自动提交属性设置为 true
  • 我真的不知道这个属性,但我做了一些谷歌搜索并尝试了这些:spring.datasource.auto-commit,spring.jpa.hibernate.autocommit, spring.jpa.hibernate.auto-提交,spring.jpa.properties.hibernate.autocommit,spring.jpa.properties.hibernate.auto-commit,hibernate.connection.autocommit,hibernate.connection.auto-commit。没有工作
  • 你是对的,只需添加@Transactional 就足够了。我在更改代码以进行测试时犯了一些愚蠢的错误,一开始并没有用。
【解决方案2】:

你忽略了依赖注入,这是 spring 框架的美妙之处。

  1. 创建一个实现 JPARepository 的 Repository 类并使用 @Repository 对其进行注释。
  2. 创建一个服务类并使用@Service 和@Transactional 对其进行注释。
  3. 在 Service 类中自动装配 Repository 并调用相应的方法,如 .save() .find() 等。
  4. 在控制器类中自动装配服务类并调用将调用存储库方法的服务方法。

这就是你所要做的。 为了使您的应用程序快速运行,最好为实体类创建模型并在类之间而不是实体之间传递模型,因为它包含更多信息,因此比普通模型对象重得多。

【讨论】:

  • Repositories 由 Spring Data JPA 自动实现,因此您不必自己实现。
  • 是的,但是要创建更多方法,您需要创建一个接口,并且可以在其中添加抽象方法,其余的实现将在spring中给出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-03
  • 2019-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多