2017-06-13 130 views
0

我正在通过XML与SprinBoot/JPA进行集成。我必须读取一个XML文件并将数据保存到我的数据库中。 步骤:Hibernate抛出StackOverflow异常(Spring Boot)

  • 我必须验证,如果这个XML不是经常性的,如果它是,我必须更新这个寄存器。
  • 每个XML都带有一个项目列表,我必须验证每个孩子是否已经存在,是否必须更新,如果没有,我必须创建一个新的。

  • 我必须验证某些孩子是否经常性,如果不是,我必须删除此项。

  • 我必须验证材料,颜色和产品是否存在,否则我必须为每种情况创建一个新的。

一般来说,一切工作正常。但我有一些情况下,当我得到一个StackOverflow异常。

  • 这不是因为它是递归的,因为90%的文件被正确保存并正确更新。

  • 我试图分开保存孩子,没有成功。

  • 它总是与抛出异常的文件相同。

  • 这不是内存,因为我有成功案例,该文件比失败的文件大。

  • 我可以多次保存成功文件,并且不会发生错误,但是如果我尝试保存一个有问题的错误并发生异常。

这是我的课负责管理加载XML和持续

@Override 
    public void createProductionSet(ClientOrder clientOrder) throws Exception { 
     try{ 
      List<Long> recurrent = new ArrayList<>(); 
      ProductionOrder order = orderService.findByCodeAndClientCode(clientOrder.getOp(), clientOrder.getClientCode()); 
      boolean newProdOrder = order == null, 
        hasChildrenInfo = hasChildrenInfo(clientOrder); 

      if(newProdOrder) 
       order = new ProductionOrder(clientOrder.getOp(), clientOrder.getClientCode(), clientOrder.getObservation()); 
      order.setItems(new ArrayList<>()); 
      if(hasChildrenInfo) 
       manageCollectionChildrenValues(clientOrder, order, newProdOrder, recurrent); 
      else 
       manageCollection(clientOrder, order, newProdOrder,recurrent, 
           loadColor(clientOrder.getColorReference(), clientOrder.getColor()), 
           loadMaterial(clientOrder.getMaterialReference(), clientOrder.getMaterial()), 
           loadProduct(clientOrder.getProductReference(), clientOrder.getProduct(), clientOrder.getUnitOfMeasurement())); 

      if(!newProdOrder) 
       prodOrderItemService.deleteNotIn(recurrent, order.getId()); 
      orderService.save(order); 
     } catch(StackOverflowError t) { 
      throw new Exception("Erro de StackOverflowError : "+clientOrder.toString()); 
     }catch (Exception e){ 
      log.warn("ERRO >> "+e.getMessage()); 
     } 
    } 

    private void manageCollection(ClientOrder clientOrder, ProductionOrder order, boolean newProdOrder, List<Long> recurrent, 
            MaterialColor materialColor, Material material, Product product) { 
     for(ItemOrder item : clientOrder.getItems()) { 
      item.setColorObj(materialColor); 
      item.setMaterialObj(material); 
      item.setProductObj(product); 
      manageItem(item, order, newProdOrder, recurrent); 
     } 
    } 

    private void manageCollectionChildrenValues(ClientOrder clientOrder, ProductionOrder order, boolean newProdOrder, List<Long> recurrent) { 
     for(ItemOrder item : clientOrder.getItems()) { 
      item.setColorObj(loadColor(item.getColorReference(), item.getColor())); 
      item.setMaterialObj(loadMaterial(item.getMaterialReference(), item.getMaterial())); 
      item.setProductObj(loadProduct(item.getProductReference(), item.getProduct(), clientOrder.getUnitOfMeasurement())); 
      manageItem(item, order, newProdOrder, recurrent); 
     } 
    } 

    private void manageItem(ItemOrder item, ProductionOrder order, boolean newProdOrder, List<Long> recurrent) { 
     ProdOrderItem aux = null; 
     if(!newProdOrder) 
      aux = prodOrderItemService.findOneByProductionOrderAndSize(order.getId(), item.getSize()); 

     if(aux != null) { 
      aux.update(item); 
      recurrent.add(aux.getId()); 
     }else { 
      aux = new ProdOrderItem(item, order); 
      order.getItems().add(aux); 
     } 
    } 

    private boolean hasChildrenInfo(ClientOrder clientOrder) { 
     return clientOrder.getColorReference() == null 
       && clientOrder.getProductReference() == null 
       && clientOrder.getMaterialReference() == null; 
    } 

    private Product loadProduct(String reference, String description, String unitOfMeasurement) { 
     if(reference != null && !reference.isEmpty()) { 
      Product product = productService.findProductByReference(reference); 
      if (product != null) 
       return product; 
      return productService.save(new Product(description, reference, unitOfMeasurement)); 
     } 
     return productService.loadFirstOrDefault(); 
    } 

    private MaterialColor loadColor(String reference, String description) { 
     if(reference != null && !reference.isEmpty()) { 
      MaterialColor materialColor = colorService.findByReference(reference); 
      if (materialColor != null) 
       return materialColor; 
      return colorService.save(new MaterialColor(reference, description)); 
     } 
     return colorService.loadFirstOrDefault(); 
    } 

    private Material loadMaterial(String reference, String description) { 
     if(reference != null && !reference.isEmpty()) { 
      Material material = materialService.findByReference(reference); 
      if (material != null) 
       return material; 
      return materialService.save(new Material(description, reference, null)); 
     } 
     return materialService.loadFirstOrDefault(); 
    } 
} 

这是我的模型:

@Entity(name = "production_order") 
public class ProductionOrder { 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private long id; 

@Temporal(TemporalType.TIMESTAMP) 
private Date created; 

@Temporal(TemporalType.TIMESTAMP) 
private Date updated; 

@Type(type = "org.hibernate.type.NumericBooleanType") 
private boolean deleted; 

@Column(nullable = false, length = 30) 
private String code; 

@Column(length = 30) 
private String clientCode; 

@Column(length = 200) 
private String observation; 

@OneToMany(fetch = FetchType.EAGER, mappedBy ="productionOrder", orphanRemoval = true, cascade = {CascadeType.ALL}) 
@Cascade({org.hibernate.annotations.CascadeType.ALL}) 
private List<ProdOrderItem> items; 

... 

}

@Entity(name = "order_item") 
public class ProdOrderItem { 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

@Column(nullable = false, length = 10) 
private String size; 

@Column(nullable = false) 
private float quantity; 

@Column(nullable = false) 
private float weight; 

@Column(nullable = false) 
private float tolerance; 

@Temporal(TemporalType.TIMESTAMP) 
private Date created; 

@Temporal(TemporalType.TIMESTAMP) 
private Date updated; 

@Type(type = "org.hibernate.type.NumericBooleanType") 
private boolean deleted; 

@ManyToOne(optional = false) 
@JoinColumn(name = "product_id") 
private Product product; 

@ManyToOne(optional = false) 
@JoinColumn(name = "color_id") 
private MaterialColor color; 

@ManyToOne(optional = false) 
private Material material; 

@ManyToOne 
@JoinColumn(name = "characteristic_id") 
private Characteristic characteristic; 

@ManyToOne(optional = false) 
@JoinColumn(name="order_id") 
private ProductionOrder productionOrder; 

这是日志:

java.lang.StackOverflowError 
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:131) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108) 
    at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81) 
    at com.sun.proxy.$Proxy106.prepareStatement(Unknown Source) 
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146) 
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172) 
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148) 
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1929) 
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1898) 
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1876) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:919) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:306) 
    at org.hibernate.loader.Loader.loadEntity(Loader.java:2204) 
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:60) 
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:50) 
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4019) 
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508) 
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478) 
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219) 
    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:278) 
    at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:121) 
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89) 
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1129) 
    at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1022) 
    at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:639) 
    at org.hibernate.type.EntityType.resolve(EntityType.java:431) 
    at org.hibernate.type.ComponentType.resolve(ComponentType.java:687) 
    at org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:848) 
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:714) 
    at org.hibernate.loader.Loader.processResultSet(Loader.java:972) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:930) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:306) 
    at org.hibernate.loader.Loader.loadEntity(Loader.java:2204) 
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:60) 
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:50) 
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4019) 
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508) 
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478) 
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219) 
    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:278) 
    at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:121) 
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89) 
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1129) 
    at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1022) 
    at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:639) 
    at org.hibernate.type.EntityType.resolve(EntityType.java:431) 
    at org.hibernate.type.ComponentType.resolve(ComponentType.java:687) 
    at org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:848) 
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:714) 
    at org.hibernate.loader.Loader.processResultSet(Loader.java:972) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:930) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:306) 
    at org.hibernate.loader.Loader.loadEntity(Loader.java:2204) 
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:60) 
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:50) 
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4019) 
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508) 
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478) 
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219) 
    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:278) 
    at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:121) 
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89) 
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1129) 
    at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1022) 
    at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:639) 
    at org.hibernate.type.EntityType.resolve(EntityType.java:431) 
    at org.hibernate.type.ComponentType.resolve(ComponentType.java:687) 
    at org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:848) 
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:714) 
    at org.hibernate.loader.Loader.processResultSet(Loader.java:972) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:930) 
    at 

完整的日志here, together with 2 xml files

+0

为什么你认为你需要两个'@OneToMany(级联= ALL )'和'@Cascade(ALL)'? – crizzis

+0

我的错误。我也必须消除渴望。 –

回答

0

的原因可能是在FetchType.EAGER尝试将其删除:

@Entity(name = "production_order") 
public class ProductionOrder { 
.... 
@OneToMany(mappedBy ="productionOrder", cascade = {CascadeType.ALL}) 
@Cascade({org.hibernate.annotations.CascadeType.ALL}) 
private List<ProdOrderItem> items; 
+0

我试过了。之前是懒惰的,同样的事情发生了。 –