【发布时间】:2018-08-16 14:56:33
【问题描述】:
问题是有一天我们发现如果我们将一个对象保存在 Spring Boot 存储库中,另一个以相同方法更改的对象也会更新并持久化到数据库中。
人们非常好奇为什么会发生这种情况。我使用Spring Initializr 和一些模板代码创建了示例项目来展示实际情况(尽量保持依赖的数量尽可能少)。
使用 Spring boot 版本 1.5.11 (SNAPSHOT) 并且项目具有以下依赖项:
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.mariadb.jdbc:mariadb-java-client:2.1.0')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
现在进入重点:
项目有两个实体,Pet:
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Pet.class)
public class Pet {
@Id
@GeneratedValue
private long id;
private String type;
public Pet() {}
public String getType() { return type; }
public void setType(String type) { this.type = type; }
}
和User:
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = User.class)
public class User {
@Id
@GeneratedValue
private long id;
private String name;
public User() {}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
这两个实体也都有存储库,Pet:
@Repository
public interface PetRepository extends CrudRepository<Pet, Long> {
Pet findPetById(Long id);
}
User:
@Repository
public interface UserRepository extends CrudRepository<User, Long> {
User findUserById(Long id);
}
还有一个真正发生魔法的简单服务(我预先保存了一个 Pet 和一个 User 对象,具有不同的名称和类型)
@Service
public class UserService {
@Autowired
UserRepository userRepository;
@Autowired
PetRepository petRepository;
public User changeUserAndPet() {
User user = userRepository.findUserById(1L);
Pet pet = petRepository.findPetById(1L);
user.setName("Kevin");
pet.setType("Cow");
userRepository.save(user);
return user;
}
}
在调用userRepository.save(user); 之后,Pet 对象也在数据库中更新为新类型的“Cow”。如果我只保存 User 对象,为什么会发生这种情况?这是故意的吗?
还有一个简单的控制器和简单的测试端点来调用服务方法,这很可能对问题并不重要,但为了完整起见,我还是在这里添加它。
@RestController
public class UserController {
@Autowired
UserService userService;
@RequestMapping(value = "/test", method = RequestMethod.GET)
public User changeUserAndPet() {
return userService.changeUserAndPet();
}
}
感谢任何解释/提示,并随时在 github 中询问更多信息/代码。
【问题讨论】:
-
启用 jpa 日志并查看执行的查询。
-
我知道查询是针对两个更新执行的,我只是想知道是什么触发了
Pet对象的更新查询:)
标签: java spring spring-mvc jpa spring-boot