我有一个控制器ProjectContoller
,该控制器应该接收一个ProjectDto
并将其保存到我的数据库中。
我得到了以下代码:
@Autowired
ProjectService projectService;
@PostMapping(value = ControllerConstants.CREATE_NEW_PROJECT)
public ResponseEntity createProject(@RequestBody ProjectDto project) {
this.logger.info("Creating Project " + project.toString());
this.projectService.saveProject(project);
return ResponseEntity.ok(HttpStatus.OK);
}
我的ProjectService
:
@Autowired
private EntityManager entityManager;
@Autowired
private ProjectConverter projectConverter;
@Override
public void saveProject(ProjectDto projectDto) {
ProjectEntity entity = this.projectConverter.convertDtoToEntityWithDefaultFactory(projectDto);
}
自动连线的ProjectConverter
:
@Autowired
private FactoryEntityService factoryService;
@Autowired
private ProjectRoleEntityService projectRoleService;
@Autowired
private UserRepository userRepository;
@Autowired
private EntityManager entityManager;
@Transactional
public ProjectEntity convertDtoToEntityWithDefaultFactory(ProjectDto projectDto) {
FactoryEntity defaultFactory = this.factoryService.getOrCreateFactoryEntity(projectDto.getProjectArea());
ProjectEntity projectEntity = new ProjectEntity(projectDto.getProjectNumber(), projectDto.getProjectName(),
defaultFactory, ProjectState.ACTIVE);
UserEntity userEntity = this.userRepository.findUserByShorthand(projectDto.getManagerShorthand()).get();
ProjectRoleEntity projectRole = this.projectRoleService.getManagerProjectRoleEntity();
UserProjectRoleAssignment assignment = new UserProjectRoleAssignment(projectRole, projectEntity, userEntity);
projectEntity.addAssignment(assignment);
userEntity.addAssignment(assignment);
projectRole.addAssignment(assignment);
if (this.entityManager.contains(projectEntity)) {
this.entityManager.merge(projectEntity);
} else {
this.entityManager.persist(projectEntity);
}
this.entityManager.persist(assignment);
this.entityManager.flush();
return projectEntity;
}
ProjectEntity:
@Entity
@Table(name = "PV_PROJECT")
public class ProjectEntity {
@Id
@Column(name = "NUMBER")
private String projectNumber;
@Column(name = "NAME", nullable = false)
private String projectName;
@Column(name = "CREATED", nullable = false)
private LocalDateTime createdDate = LocalDateTime.now();
@Column(name = "LASTUPDATE", nullable = false)
private LocalDateTime lastupdated = LocalDateTime.now();;
@Enumerated(EnumType.STRING)
@Column(name = "STATE", nullable = false)
private ProjectState state;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "FACTORY_ID")
private FactoryEntity factory;
@OneToMany(mappedBy="id.project", cascade= {CascadeType.ALL})
private Set<UserProjectRoleAssignment> assignments = new HashSet<UserProjectRoleAssignment>();
//Getter, Setter, Constructor...
}
还有工厂:
@Entity
@Table(name = "PV_FACTORY")
public class FactoryEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private int id;
@Column(name = "NAME", nullable = false, unique = true)
private String name;
@OneToMany(
mappedBy = "factory",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<ProjectEntity> projects = new ArrayList<ProjectEntity>();
@OneToMany(
mappedBy = "factory",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<UserEntity> users = new ArrayList<UserEntity>();
}
因此,在调用此控制器API时,我得到以下输出:(启用了休眠调试)
2018-12-19 01:20:34.018 TRACE 21400 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [1]
2018-12-19 01:20:34.022 TRACE 21400 --- [nio-8080-exec-5] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [1]
2018-12-19 01:20:34.026 DEBUG 21400 --- [nio-8080-exec-3] org.hibernate.SQL : SELECT * FROM PV_PROJECTROLE p WHERE p.name = ?
Hibernate: SELECT * FROM PV_PROJECTROLE p WHERE p.name = ?
2018-12-19 01:20:34.026 TRACE 21400 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Project Manager]
2018-12-19 01:20:34.030 DEBUG 21400 --- [nio-8080-exec-3] org.hibernate.SQL : insert into pv_projectrole (name) values (?)
Hibernate: insert into pv_projectrole (name) values (?)
2018-12-19 01:20:34.034 TRACE 21400 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Project Manager]
2018-12-19 01:20:34.038 DEBUG 21400 --- [nio-8080-exec-3] org.hibernate.SQL : insert into pv_factory (name) values (?)
Hibernate: insert into pv_factory (name) values (?)
2018-12-19 01:20:34.038 TRACE 21400 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [SD]
2018-12-19 01:20:34.042 DEBUG 21400 --- [nio-8080-exec-3] org.hibernate.SQL : insert into pv_project (created, factory_id, lastupdate, name, state, number) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into pv_project (created, factory_id, lastupdate, name, state, number) values (?, ?, ?, ?, ?, ?)
2018-12-19 01:20:34.046 TRACE 21400 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [TIMESTAMP] - [2018-12-19T01:20:33.958]
2018-12-19 01:20:34.050 TRACE 21400 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [INTEGER] - [2]
2018-12-19 01:20:34.050 TRACE 21400 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [TIMESTAMP] - [2018-12-19T01:20:33.958]
2018-12-19 01:20:34.050 TRACE 21400 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [Name]
2018-12-19 01:20:34.050 TRACE 21400 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [6] as [VARCHAR] - [Number]
2018-12-19 01:20:34.054 WARN 21400 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1452, SQLState: 23000
2018-12-19 01:20:34.054 ERROR 21400 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : Cannot add or update a child row: a foreign key constraint fails (`pvdev`.`pv_project`, CONSTRAINT `pv_project_ibfk_1` FOREIGN KEY (`FACTORY_ID`) REFERENCES `pv_projectfactory` (`id`))
2018-12-19 01:20:34.142 ERROR 21400 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`pvdev`.`pv_project`, CONSTRAINT `pv_project_ibfk_1` FOREIGN KEY (`FACTORY_ID`) REFERENCES `pv_projectfactory` (`id`))
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) ~[mysql-connector-java-8.0.13.jar!/:8.0.13]
我似乎对新创建的条目有问题-当我在调用控制器方法createProject
之前确保数据库中已有一个条目时,一切正常。 (至少不会引发异常)