Я недавно использую Spring Boot и Hibernate, и я работаю над проектом, который имеет простую ассоциацию «многие ко многим». Спортивный центр имеет множество услуг и наоборот. Когда я пытаюсь ввести JSON, как это, чтобы создать новый спортивный центр и связать некоторые существующие услуги:
{
"name" : "SC1",
"address" : "Street 1111",
"description" : "A Sport center",
"email" : "sc@sc.com",
"phones" : [{"number" : "123456"}, {"number" : "654321"}],
"services" : [{"idService" : 1}, {"idService" : 2}],
"commune" : {"idCommune" : 1},
"users" : [{"idUser":62}]
}
Я получаю эту ошибку:
2018-06-25 03:56:32.670 DEBUG 20696 --- [nio-8080-exec-6] org.hibernate.SQL : insert into sport_center (address, Commune_idCommune, description, email, name) values (?, ?, ?, ?, ?)
2018-06-25 03:56:32.671 TRACE 20696 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Street 1111]
2018-06-25 03:56:32.671 TRACE 20696 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [INTEGER] - [1]
2018-06-25 03:56:32.671 TRACE 20696 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [A Sport center]
2018-06-25 03:56:32.671 TRACE 20696 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [sc@sc.com]
2018-06-25 03:56:32.671 TRACE 20696 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [VARCHAR] - [SC1]
2018-06-25 03:56:32.800 DEBUG 20696 --- [nio-8080-exec-6] org.hibernate.SQL : insert into phone (number, Sport_center_idSport_Center) values (?, ?)
2018-06-25 03:56:32.800 TRACE 20696 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [123456]
2018-06-25 03:56:32.800 TRACE 20696 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [INTEGER] - [252]
2018-06-25 03:56:32.942 DEBUG 20696 --- [nio-8080-exec-6] org.hibernate.SQL : insert into phone (number, Sport_center_idSport_Center) values (?, ?)
2018-06-25 03:56:32.942 TRACE 20696 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [654321]
2018-06-25 03:56:32.942 TRACE 20696 --- [nio-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [INTEGER] - [252]
2018-06-25 03:56:33.368 ERROR 20696 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.eiffel.canchai.model.Service; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.eiffel.canchai.model.Service] with root cause
org.hibernate.PersistentObjectException: detached entity passed to persist: com.eiffel.canchai.model.Service
Важно отметить, что я уже добавил несколько строк в служебную таблицу. Итак, идея состоит в том, чтобы добавить спортивный центр и связать с ним эти услуги.
Не могли бы вы помочь мне с этим?
Мои занятия ниже:
SportCenter.java
@Entity
@Table(name = "sport_center")
public class SportCenter implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idSport_Center")
private Integer idSportCenter;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
@Column(name = "description")
private String description;
@Column(name = "email")
private String email;
@JoinTable(name = "sport_center_has_user", joinColumns = {
@JoinColumn(name = "Sport_center_idSport_Center", referencedColumnName = "idSport_Center")}, inverseJoinColumns = {
@JoinColumn(name = "User_idUser", referencedColumnName = "idUser")})
@ManyToMany(cascade = CascadeType.ALL)
private List<User> users;
@JoinTable(name = "sport_center_has_service", joinColumns = {
@JoinColumn(name = "Sport_center_idSport_Center", referencedColumnName = "idSport_Center")}, inverseJoinColumns = {
@JoinColumn(name = "Service_idService", referencedColumnName = "idService")})
@ManyToMany(cascade = CascadeType.ALL)
private List<Service> services;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "sportCenter")
@JsonIgnore
private List<ImageField> imageFields;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "sportCenter")
@JsonIgnore
private List<Field> fields;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "sportCenter", fetch = FetchType.LAZY)
private List<Phone> phones;
@JoinColumn(name = "Commune_idCommune", referencedColumnName = "idCommune")
@ManyToOne(optional = false)
private Commune commune;
public SportCenter() {
}
Service.java
@Entity
@Table(name = "service")
public class Service implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idService")
private Integer idService;
@Column(name = "name")
private String name;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "services", cascade = CascadeType.ALL)
@JsonIgnore
private List<SportCenter> sportCenters;
public Service() {
}
ServiceDao.java
@Repository
@Transactional
public class ServiceDao implements IServiceDao {
@PersistenceContext
private EntityManager entityManager;
@Override
public void save(Service entity) {
entityManager.persist(entity);
}
* * * * * * * * * * * * * * * * * * * * * * * * *
).
Контроллер
@Controller
@RequestMapping("/sportcenter")
@CrossOrigin
public class SportCenterController {
@Autowired
private ISportCenterService sportCenterService;
@PostMapping("/register")
public ResponseEntity<?> registerSportCenter(@RequestBody SportCenter sc){
if (sc.getEmail().length() == 0 || sc.getName().length() == 0 || sc.getAddress().length() == 0 || sc.getPhones().size() == 0 || sc.getServices().size() == 0) {
return new ResponseEntity(new ErrorMsg("Check parameters. One of them is missing"),HttpStatus.NO_CONTENT);
}
for (Phone p : sc.getPhones()) {
p.setSportCenter(sc);
}
for (Service s : sc.getServices()) {
s.addSportCenters(sc);
}
sportCenterService.save(sc);
return new ResponseEntity(HttpStatus.OK);
}
Я думаю, что это, вероятно, ошибка сопоставления ассоциаций, но я не уверен.
Кроме того, если вы видите, что есть способ улучшить мой код, пожалуйста, дайте мне знать :) .. Советы всегда хороши.
Я использую Spring Boot V2.0.3 и Hibernate 5.3
Заранее спасибо!