У меня есть проблема, я не знаю, как отследить StackOverFlowError, он говорит, и преобразование в типы данных в порядке, но я не знаю, из-за чего возникает ошибка: Как исправить эту проблему? Подскажите, пожалуйста, как лучше всего отследить эту ошибку, чтобы сгенерировать список и сохранить его в базе данных?

    at java.lang.String.valueOf(String.java:2994)
    at java.lang.StringBuilder.append(StringBuilder.java:131)
    at com.pioneer.ams.backend.entity.AbstractEntity.toString(AbstractEntity.java:178)
    at java.lang.String.valueOf(String.java:2994)
    at java.lang.StringBuilder.append(StringBuilder.java:131)
    at java.util.AbstractCollection.toString(AbstractCollection.java:462)
    at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:510)
    at java.lang.String.valueOf(String.java:2994)

Вот мой код:

- EmployeeService.java -

@Autowired
private EmployeeRepository employeeRepository;

public List<Map<String, String>> uploadEmployee(MultipartFile multip) throws Exception {

String fileNames = multip.getOriginalFilename();

DataFormatter formatter = new DataFormatter();

File file = new File("./reports/" + fileNames);
Workbook workbook = WorkbookFactory.create(file);

FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();

Sheet sheet = workbook.getSheetAt(0);

int headerRowNum = sheet.getFirstRowNum();

Map<Integer, String> colHeaders = new HashMap<Integer, String>();
Row row = sheet.getRow(headerRowNum);
for (Cell cell : row) {
    int colIdx = cell.getColumnIndex();
    String value = formatter.formatCellValue(cell, evaluator);
    colHeaders.put(colIdx, value);
}

  List<Employee> content = new ArrayList<>();
  for (int r = headerRowNum + 1; r <= sheet.getLastRowNum(); r++) {
   row = sheet.getRow(r);
   if (row == null)
      continue;
   Employee employee = new Employee();
   for (Map.Entry<Integer, String> entry : colHeaders.entrySet()) {
    int colIdx = entry.getKey();
    Cell cell = row.getCell(colIdx);
    if (cell != null) {
        String cellValue = formatter.formatCellValue(cell, evaluator);
        switch(entry.getValue()) {
             case "lastname": {
                  employee.setLastName(cellValue);
                  break;
             }
             case "firstname": {
                  employee.setFirstName(cellValue);
                   break;
             }
             case "mi": {
                  employee.setMiddleInitial(cellValue);
                   break;
             }
             case "rank": {
                  employee.setRank(cellValue);
                   break;
             }
             case "emp_id": {
                  employee.setEmpId(cellValue);
                   break;
             }
             case "po_company_id": {
                 POCompany poCompanyId = poCompanyRepository.findById(Long.parseLong(cellValue));
                  employee.setPoCompany(poCompanyId);
                  break;
             }
             case "business_id": {
                 Business businessId = businessRepository.findById(Long.parseLong(cellValue));
                  employee.setBusiness(businessId);
                   break;
             }
             case "department_id": {
                 Department departmentId = departmentRepository.findById(Long.parseLong(cellValue));
                  employee.setDepartment(departmentId);
                   break;
             }
             case "status_id": {
                 Status statusId = statusRepository.findById(Long.parseLong(cellValue));
                  employee.setStatus(statusId);
                   break;
               }
          }
          employeeRepository.save(employee);
       }
    }
    content.add(employee);
}

workbook.close();

System.out.println(content);

return content;
}

- Employee.java -

@Entity
@Table(name = "employee")
public class Employee extends AbstractEntity<Long> {

private static final long serialVersionUID = 1L;

@Column(name = "lastname", length = 200)
private String lastName;

@Column(name = "firstname")
private String firstName;

@Column(name = "mi")
private String middleInitial;

@Column(name = "rank", nullable = true)
private String rank;

@Column(name = "emp_id")
private String empId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "po_company_id")
private POCompany poCompany;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "business_id")
private Business business;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Department department;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "status_id")
private Status status;

public Employee() {
    super();
}

public Employee(String empId, String lastName, String firstName, String middleInitial, String rank,
        List<User> user) {
    this();
    this.empId = empId;
    this.lastName = lastName;
    this.firstName = firstName;
    this.middleInitial = middleInitial;
    this.rank = rank;
    this.user = user;
}

public String getEmpId() {
    return empId;
}

public void setEmpId(String empId) {
    this.empId = empId;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getMiddleInitial() {
    return middleInitial;
}

public void setMiddleInitial(String middleInitial) {
    this.middleInitial = middleInitial;
}

public String getRank() {
    return rank;
}

public void setRank(String rank) {
    this.rank = rank;
}

public Department getDepartment() {
    return department;
}

public void setDepartment(Department department) {
    this.department = department;
}

public Status getStatus() {
    return status;
}

public void setStatus(Status status) {
    this.status = status;
}

public Business getBusiness() {
    return business;
}

public void setBusiness(Business business) {
    this.business = business;
}

public void setBranch(Branch branch) {
 this.branch = branch;
}

public POCompany getPoCompany() {
    return poCompany;
}

public void setPoCompany(POCompany poCompany) {
    this.poCompany = poCompany;
}
}

- EmployeeController.java -

@RequestMapping(value = "/uploadEmployee", method = RequestMethod.POST)
public ResponseEntity<List<Employee>> uploadEmployee(MultipartFile file) throws Exception{

    return new ResponseEntity<List<Employee>>(employeeService.uploadEmployee(file), HttpStatus.OK);
}
0
Bryan Caliwag 22 Ноя 2019 в 04:41
Взгляните на stackoverflow.com/a/56477233/8112217
 – 
tsarenkotxt
22 Ноя 2019 в 05:06

2 ответа

Вероятно, вы столкнулись с проблемой из-за того, что вы возвращаете объект сущности Employee.class непосредственно из своей конечной точки. В своем классе сущности сотрудника у вас есть @ManyToOne отношения с несколькими таблицами. Таким образом, Jpa разрешит все эти отношения и заполнит поля. В вашем Business.class или другом классе сущности, который вы использовали в своем коде, у вас может быть двунаправленное отображение отношения к сотруднику. Итак, когда Джексон пытается преобразовать этот класс в json, это может вызвать ошибку StackOverflow в результате ссылки Infinite.

Используйте аннотации, такие как @JsonBackReference и @JsonManagedBackReference, чтобы предотвратить бесконечный цикл в возвращаемом классе сущности. Лучший подход - создать объект DTO и сопоставить поля сущности с объектом DTO и вернуть объект DTO из конечной точки. .

`@JsonManagedReference` is the forward part of reference – the one that gets serialized normally.
`@JsonBackReference` is the back part of reference – it will be omitted from serialization.

Если это не помогло, предоставьте более подробную информацию, например, всю трассировку стека, а также классы сущностей, на которые есть ссылки в классе сущностей Employee. Прочтите Руководство.

2
Ananthapadmanabhan 22 Ноя 2019 в 09:49

Ошибка довольно ясна:

на com.pioneer.ams.backend.entity.AbstractEntity.toString (AbstractEntity.java:178)

Итак, у вас есть реализация toString(), которая создает круговой цикл, т.е.

A.toString(){
    //references B.toString();
}

B.toString(){
    //references A.toString();
}
0
Alan Hay 22 Ноя 2019 в 17:11