我有一個 csv 檔案,其中包含員工和專案資訊串列(每個員工都有多個專案)。我上傳檔案,決議 csv 并分別建立父子關系-> Employee 和 Projects 并將其保存到資料庫。
下面是我的員工物體類(我嘗試了評論部分但沒有運氣)
@Entity
@Table(name = "employees")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@NotNull
private String name;
@NotNull
private String empId;
@NotNull
private String department;
//@OneToMany(fetch = FetchType.LAZY, mappedBy = "transcript", cascade = CascadeType.ALL) //tried didn't work
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "employee", orphanRemoval = true)
private List<Project> projects;
public Employee(String name, String empId, String department) {
this.name = name;
this.empId = empId;
this.department = department;
}
}
下面是我的專案物體類
@Entity
@Table(name = "projects")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String projectName;
private String projectCode;
private Instant projectStartDate;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "employee_id", nullable = false)
@JsonBackReference
private Employee employee;
public Project(String name, String code, Instant time) {
this.projectName = name;
this.projectCode = code;
this.projectStartDate = time;
}
}
這是我試圖保存我的 Employee 物件的地方:
@Transactional
public void uploadEmployees(MultipartFile file) {
try {
//calls csv helper that does all the parsing and brings into Employee model object format
Set<Employess> employees = CSVHelper.csvToEmployess(file.getInputStream(), "2");
employeeRepository.saveAll(employees);
System.out.println("I processed all the records of cdv into java");
} catch (IOException e) {
throw new RuntimeException(e);
}catch (Exception e ){
throw new RuntimeException(e.getMessage());
}
}
上述方法拋出:
2022-09-11T22:30:08.438-05:00 ERROR 63321 --- [nio-8086-exec-5] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: null value in column "employee_id" of relation "projects" violates not-null constraint
Detail: Failing row contains (6, p1, 123, 0184-06-08T01:07:47Z, null).
如果我將 id 生成型別更改為 @GeneratedValue(strategy = GenerationType.AUTO) :我得到以下例外:
2022-09-12T00:55:09.465-05:00 WARN 73014 --- [nio-8086-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42P01
2022-09-12T00:55:09.465-05:00 ERROR 73014 --- [nio-8086-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist
Position: 17
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy2/jdk.proxy2.$Proxy133.saveAll(Unknown Source)
就在執行 saveAll 方法之前,我嘗試使用除錯器查看員工串列的外觀,如下所示:
Employee(id=0, name="test", empId="4511504557911789", department="JJ967W"
projects=[
Project(id=0, projectName="p1", projectCode="123", projectStartDate="0184-06-08T01:07:47Z", employee=null),
Project(id=0, projectName="p2", projectCode="345", projectStartDate="0184-06-08T01:07:47Z", employee=null)
]
)
我認為employee=null是有道理的,因為它還沒有保存到資料庫中。
請幫助我解決我在這里缺少的導致此問題的原因。非常感謝您花時間提供幫助。
**** 更新 ****
添加我正在添加決議 CSV 并構建 Employee 和 Project 物件的部分
public static Set<Employee> csvToTranscripts(InputStream is) throws IOException {
try (BufferedReader fileReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
CSVParser csvParser = new CSVParser(fileReader,
CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim());) {
Set<Employee> employees = new HashSet<>();
List<CSVRecord> csvRecordsList = csvParser.getRecords();
Employee employee = null;
List<String> empIds = new ArrayList<>();
List<Project> projects = null;
//iterate through list and create project list for new emp_id
for(CSVRecord csvRecord : csvRecordsList){
if(employees.isEmpty() || !empIds.contains(csvRecord.get("EMP_ID"))){
employee = new Employee(
csvRecord.get("NAME"),
csvRecord.get("EMP_ID"),
csvRecord.get("DEPARTMENT")
);
empIds.add(csvRecord.get("EMP_ID")); //this is mainly to check for unique emp id
projects = new ArrayList<>();
}
Project project = new Project(csvRecord.get("NAME"),
csvRecord.get("CODE"),
formatToInstant(csvRecord.get("TIME")) );
project.setEmployee(employee);//setting employee to project here
projects.add(project);
employee.setProjects(projects); //setting projects list to employee here
employees.add(employee);
}
return employees;
} catch (IOException e) {
throw new RuntimeException("fail to parse CSV file: " e.getMessage());
}
}
************ 已解決 ****************** 感謝大家的幫助。將員工設定為專案解決了該問題。我真是個笨蛋!!!
project.setEmployee(employee);
uj5u.com熱心網友回復:
@M.Deinum 進一步評論 - 在您的 Employee 類中宣告這樣的方法,并使用它向員工添加專案,確保雙向關系保持同步
public void addProject(Project project) {
if (projects == null) {
projects = new ArrayList<>();
}
project.setEmployee(this);
projects.add(project);
}
uj5u.com熱心網友回復:
我認為 employee=null 是有道理的,因為它還沒有保存到資料庫中。
這是錯誤的。如果您保存具有雙向關系的專案,那么當孤兒Project存在而沒有Employee. 因此,在呼叫 any 之前,CrudRepository.save*()您必須確保所有projects參考 some Employee。
通常在這種情況下,當您向員工添加專案時,您會這樣做:
// method of Employee class
public void addAll(Projects projects) {
for (Project : projects) {
project.setEmployee(this);
}
this.projects.addAll(projects);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/506418.html
上一篇:java.lang.StackOverflowError:com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFiel
