I have a server using spring boot and spring data jpa.
I have two classes annotated with @RestController
in my server. One of them might change entities, while the other won't.
@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
}
}
Here are the two entities and the repository:
@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> {
}
I make a call to ControllerA.changeEntity from the client, and once that returns, I make another call to ControllerB.getEntity. The changes I made in the first call aren't shown in the second call, (and they're not in the database either if I query directly with sql) the int property has an old value. Even though I do the save only on the Entity and not on the linkedEntity, the CascadeType.ALL
should make the the linked entity update too, right?
I tried adding an entityRepository.flush()
after the save in ControllerA, but the issue still appears. What can I do? How can I make ControllerB get the correct value of intProperty?
This is what I have in 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
You are ignoring dependency injection which is the beauty of spring framework.
This is all you have to do. For making your application flow fast, better you create model for the entity class and pass the model between classes instead of entity as it contains a lot more information and thus much more heavy than normal model object.