Ho due entità JPA, una con un repository SDR esportato e un'altra con un controller Spring MVC e un repository non esportato.Mixing Spring MVC + Spring Data Rest produce risposte MVC dispari
L'entità esposta MVC ha un riferimento all'entità gestita DSP. Vedi sotto per il codice di riferimento.
Il problema entra in gioco quando si recupera uno User
da UserController
. L'entità gestita da SDR non verrà serializzata e sembra che Spring stia tentando di utilizzare i ref HATEOAS nella risposta.
Ecco quello che un GET
per una completamente popolato User
assomiglia:
{
"username": "[email protected]",
"enabled": true,
"roles": [
{
"role": "ROLE_USER",
"content": [],
"links": [] // why the content and links?
}
// no places?
]
}
Come posso chiaramente ritorno dell'entità User
dal mio controller con l'SDR incorporato gestito entità?
Spring MVC Managed
Entity
@Entity
@Table(name = "users")
public class User implements Serializable {
// UID
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonIgnore
private Long id;
@Column(unique = true)
@NotNull
private String username;
@Column(name = "password_hash")
@JsonIgnore
@NotNull
private String passwordHash;
@NotNull
private Boolean enabled;
// No Repository
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@NotEmpty
private Set<UserRole> roles = new HashSet<>();
// The SDR Managed Entity
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "user_place",
joinColumns = { @JoinColumn(name = "users_id") },
inverseJoinColumns = { @JoinColumn(name = "place_id")})
private Set<Place> places = new HashSet<>();
// getters and setters
}
Repo
@RepositoryRestResource(exported = false)
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
// Query Methods
}
controller
@RestController
public class UserController {
// backed by UserRepository
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping(path = "https://stackoverflow.com/users/{username}", method = RequestMethod.GET)
public User getUser(@PathVariable String username) {
return userService.getByUsername(username);
}
@RequestMapping(path = "/users", method = RequestMethod.POST)
public User createUser(@Valid @RequestBody UserCreateView user) {
return userService.create(user);
}
// Other MVC Methods
}
SDR gestito
Entity
@Entity
public class Place implements Serializable {
// UID
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@NotBlank
private String name;
@Column(unique = true)
private String handle;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "address_id")
private Address address;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "contact_info_id")
private ContactInfo contactInfo;
// getters and setters
}
Repo
public interface PlaceRepository extends PagingAndSortingRepository<Place, Long> {
// Query Methods
}
Suppongo che tu abbia annotazione @Repository per PlaceRepository - non l'hai postato qui? Potresti aggiungere anche il testo dell'eccezione? – lenach87
@ lenach87 - L'SDR non richiede l'annotazione '@ Repository' a meno che non sia necessario configurarlo ulteriormente. Non c'è anche nessuna eccezione, solo la mancanza di serializzazione. – bvulaj
Forse il problema con la tua implementazione JPA? Se stai usando Hibernate, puoi caricare solo una borsa. è possibile creare una query personalizzata per forzarla a caricarsi con entusiasmo, o semplicemente chiamare accessor della proprietà prima di inviarla come risposta (questo costringerà l'ibernazione a caricare la proprietà). –