JpaRepository 不保存实体
JpaRepository not saving entity
我有一个使用 spring 引导和 spring 数据 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,然后 returns,我再次调用 ControllerB.getEntity。我在第一次调用中所做的更改没有显示在第二次调用中,(并且如果我直接使用 sql 查询,它们也不在数据库中)int 属性 有旧值。即使我只在实体上而不是在链接实体上进行保存,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
您应该向您的方法添加 @Transactional
注释,这样 spring 将处理事务并提交您的更改。
这通常出现在@Service
class,但我在你的例子中看到你没有,所以把它放在控制器上(或者添加服务层,我认为更好)
你忽略了依赖注入,这是 spring 框架的优点。
- 创建一个实现 JPARepository 的存储库 class 并用 @Repository 对其进行注释。
- 制作一个服务class并用@Service 和@Transactional 注释它。
- 在服务中 class 自动装配存储库并调用相应的方法,如 .save() .find() 等
- 在 Controller Class 中自动装配服务 class 并调用将调用存储库方法的服务方法。
这就是您要做的全部。
为了使您的应用程序快速流动,最好为实体 class 创建模型并在 class 之间传递模型而不是实体,因为它包含更多信息,因此比普通模型对象更重。
我有一个使用 spring 引导和 spring 数据 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,然后 returns,我再次调用 ControllerB.getEntity。我在第一次调用中所做的更改没有显示在第二次调用中,(并且如果我直接使用 sql 查询,它们也不在数据库中)int 属性 有旧值。即使我只在实体上而不是在链接实体上进行保存,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
您应该向您的方法添加 @Transactional
注释,这样 spring 将处理事务并提交您的更改。
这通常出现在@Service
class,但我在你的例子中看到你没有,所以把它放在控制器上(或者添加服务层,我认为更好)
你忽略了依赖注入,这是 spring 框架的优点。
- 创建一个实现 JPARepository 的存储库 class 并用 @Repository 对其进行注释。
- 制作一个服务class并用@Service 和@Transactional 注释它。
- 在服务中 class 自动装配存储库并调用相应的方法,如 .save() .find() 等
- 在 Controller Class 中自动装配服务 class 并调用将调用存储库方法的服务方法。
这就是您要做的全部。 为了使您的应用程序快速流动,最好为实体 class 创建模型并在 class 之间传递模型而不是实体,因为它包含更多信息,因此比普通模型对象更重。