Estoy usando JPA2 y Springboot2X. Tratando de definir una relación simple de uno a uno en las tablas de User
y Account
. User
es el padre mientras que la Account
es el hijo. La relación es de padres a hijos. Seguí esto .
La tabla User
tiene una columna account_no
para contener el número de cuenta, que es la clave principal de la tabla Account
. Así que el User
tiene la clave externa.
@Entity public class Account extends AbstractEntity implements Serializable{ // fields like account#, balance etc goes here.. @OneToOne (fetch = FetchType.LAZY) private User user; } @Entity public class User extends AbstractEntity implements Serializable{ // Other fields related to user entity go here .. @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "account_no", referencedColumnName = "account_number") private Account account; }
El ahorro funciona correctamente. Pero cuando busco un usuario ( User user = userRp.findByUserID(userid);
), obtengo datos de ambas tablas. Mi pregunta es cuando defino fetch = FetchType.LAZY
¿por qué se obtienen los datos de la tabla de cuentas? Solo quiero que los datos del usuario estén en la salida como cuando ejecuto la consulta de selección en la tabla User
.
Producción :
{ "id": 1, "userID": "xxxxx", "firstName": "Dsd", "llastName": "cccc", "email": "danqsaa@brown", "creation_date": "2021-12-19 19:41", "modified_date": "2021-12-19 19:41", "account": { "id": 2, "accountNo": 6848982326, "balance": 4000.0, "creationUser": "xxx", "creation_date": "2021-12-19 19:41", "modified_date": "2021-12-19 19:41", "transactions": [] } }
Se agregaron a continuación los detalles de RestController, Service y Repo.
@RestController public class UserController { @GetMapping("/users/{userID}") public ResponseEntity<Object> getUser(@PathVariable("userID") String userID){ return new ResponseEntity<>(userServiceImpl.getUserByID(userID), HttpStatus.OK)); } } @Service public class UserService { // injected user repo public User getUserByID(String userID){ return userRepo.findByUserID(userID); } } public interface UsersRepository extends CrudRepository<User, String> { User findByUserID(String userID); }
Es lamentable que la pregunta sea engañosa y se necesitan muchos comentarios para averiguar lo que está preguntando. Finalmente entiendo: ves el campo en JSON y no quieres. Esta es una pregunta puramente relacionada con Jackson e Hibernate no tiene nada que ver con eso.
Hay varias formas de tomar:
Hay una buena razón por la que no usamos nuestras Entidades como parte de la serialización de JSON, exactamente porque es raro que satisfagan nuestros requisitos de JSON.
Entonces, en su lugar, creamos una clase DTO especial que mapea exactamente cómo la necesitamos para un punto final en particular. Convertimos nuestra Entidad a DTO (y no incluirá el campo de account
) y luego serializamos DTO.
Jackson tiene una noción de JsonView : le permite mapear el mismo objeto de manera diferente según la vista que solicite. De esta manera, puede hacer que el campo de la account
sea invisible para ese punto final en particular.
Como ya se insinuó en la otra respuesta, puede @JsonIgnore
la propiedad o deshacerse de su visibilidad o hacer que se deserialice solo con WRITE_ONLY.
Jackson tiene "complementos" específicos para Hibernate: jackson-datatype-hibernate . Permiten configurarse para ignorar campos perezosos y no inicializarlos. En tal caso, Jackson serializará nulo ( HibernateXModule.Feature ).
Esta es probablemente la peor opción de todas porque realmente no desea vincular la forma en que optimiza su trabajo con DB y su capa de presentación.