Hibernate抛出StackOverflow异常(Spring Boot)

时间:2017-06-13 20:11:17

标签: java xml spring hibernate jpa

我正在通过XML进行集成中的SprinBoot / JPA。我必须读取XML文件并将数据保存到我的数据库中。 步骤进行:

  • 我必须验证这个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

1 个答案:

答案 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;