O repositório Spring também salva objetos que não estou tentando salvar
O problema é que um dia descobrimos que, se estamos salvando um objeto no repositório de inicialização do Spring, outros objetos que são alterados no mesmo método também são atualizados e mantidos no banco de dados.
A curiosidade é enorme para descobrir por que isso realmente acontece. Eu criei um projeto de amostra usandoSpring Initializr e algum código de modelo para mostrar a situação real (tentou manter o número de dependências o mais baixo possível).
O uso do Spring boot versão 1.5.11 (SNAPSHOT) e o projeto têm as seguintes dependências:
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')
}
Agora ao ponto:
O projeto possui duas entidades,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; }
}
eUser
:
@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; }
}
Ambas as entidades também possuem repositórios,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);
}
E um serviço simples, onde a mágica realmente acontece (eu pré-salvei umPet
e umUser
objeto, com nome e tipo diferentes)
@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;
}
}
Logo após ligaruserRepository.save(user);
o objeto Pet também é atualizado no banco de dados com o novo tipo de 'Cow'. Por que exatamente isso acontece se eu apenas salvei o arquivoUser
objeto? Isso pretende ser assim?
Há também um controlador simples e um ponto de extremidade de teste simples para chamar o método de serviço que provavelmente não é importante para a questão, mas ainda o adicionarei aqui por uma questão de integridade.
@RestController
public class UserController {
@Autowired
UserService userService;
@RequestMapping(value = "/test", method = RequestMethod.GET)
public User changeUserAndPet() {
return userService.changeUserAndPet();
}
}
Quaisquer explicações / dicas são apreciadas e fique à vontade para solicitar informações / códigos extras no github.