首页 > 解决方案 > 保存对象时休眠序列进入无限循环

问题描述

我正在将 apache derby db 与休眠一起使用。我正在使用两个类 FoodOrderDBO.java 和 FoodOrderDetailsDBO.java 具有从 FoodOrderDBO 类到 FoodOrderDetailsDBO 类的一对多关系。

当我保存 FoodOrderDBO 的对象时,序列生成会重复发生。

FoodOrderDBO.java 和 FoodOrderDetailsDBO.java 如下

package rest.food.ordering.dbo;

import java.util.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonManagedReference;

import rest.food.ordering.enums.PaymentMethod;
import rest.food.ordering.enums.PaymentStatus;

@Entity
@Table(name="FOOD_ORDER")
public class FoodOrderDBO {

    @Id
    @Column(name="FOOD_ORDER_ID",nullable = false)
    private String foodOrderId;

    @Column(name="CUSTOMER_ID",nullable = false, length = 100)
    private String customerId;

    @Column(name="PAYMENT_METHOD",nullable = false)
    @Enumerated(EnumType.STRING)
    private  PaymentMethod paymentMethod;

    @Column(name="PAYMENT_STATUS",nullable = false)
    @Enumerated(EnumType.STRING)
    private PaymentStatus paymentStatus;

    @Column(name="PURCHASE_TIME_STAMP",nullable = false)
    private Date purchaseTimeStamp;

    @Column(name="TOTAL_PRICE",nullable = false)
    private double totalPrice;

    @OneToMany(fetch=FetchType.LAZY, mappedBy="foodOrder", cascade = CascadeType.ALL)
    @JsonManagedReference
    private Set<FoodOrderDetailsDBO> setOfOrderDetails;

    @OneToOne
    @JoinColumn(name="SERVING_LOCATION",nullable = false)
    private ServingLocationDBO servingLocation;

    public Set<FoodOrderDetailsDBO> getSetOfOrderDetails() {
        return setOfOrderDetails;
    }


    public void setSetOfOrderDetails(Set<FoodOrderDetailsDBO> setOfOrderDetails) {
        this.setOfOrderDetails = setOfOrderDetails;
    }

    public String getFoodOrderId() {
        return foodOrderId;
    }

    public void setFoodOrderId(String foodOrderId) {
        this.foodOrderId = foodOrderId;
    }


    public ServingLocationDBO getServingLocation() {
        return servingLocation;
    }


    public void setServingLocation(ServingLocationDBO servingLocation) {
        this.servingLocation = servingLocation;
    }


    public String getCustomerId() {
        return customerId;
    }

    public void setCustomerId(String customerId) {
        this.customerId = customerId;
    }

    public double getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(double totalPrice) {
        this.totalPrice = totalPrice;
    }

    public PaymentMethod getPaymentMethod() {
        return paymentMethod;
    }

    public void setPaymentMethod(PaymentMethod paymentMethod) {
        this.paymentMethod = paymentMethod;
    }

    public PaymentStatus getPaymentStatus() {
        return paymentStatus;
    }

    public void setPaymentStatus(PaymentStatus paymentStatus) {
        this.paymentStatus = paymentStatus;
    }

    public Date getPurchaseTimeStamp() {
        return purchaseTimeStamp;
    }

    public void setPurchaseTimeStamp(Date purchaseTimeStamp) {
        this.purchaseTimeStamp = purchaseTimeStamp;
    }

}


    package rest.food.ordering.dbo;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.SequenceGenerator;
    import javax.persistence.Table;

    import com.fasterxml.jackson.annotation.JsonBackReference;

    @Entity
    @Table(name="FOOD_ORDER_DTLS")
    public class FoodOrderDetailsDBO {

        @Id
        @GeneratedValue(generator = "FOOD_ORDER_DTLS_SEQ", strategy = GenerationType.SEQUENCE)
        @SequenceGenerator(name = "FOOD_ORDER_DTLS_SEQ", sequenceName = "FOOD_ORDER_DTLS_SEQUENCE", allocationSize=1)
        @Column(name="FOOD_ORDER_DETAILS_ID",nullable = false)
        private int foodOrderDetailsId;

        @Column(name="FOOD_QUANTITY",nullable = false)
        double foodQuantity;

        @ManyToOne
        @JoinColumn(name="FOOD_ORDER_ID",nullable = false)
        @JsonBackReference
        private FoodOrderDBO foodOrder;

        @ManyToOne
        @JoinColumn(name="FOOD_ID",nullable = false)
        private FoodDBO food;

        public double getFoodQuantity() {
            return foodQuantity;
        }

        public void setFoodQuantity(double foodQuantity) {
            this.foodQuantity = foodQuantity;
        }

        public FoodOrderDBO getFoodOrder() {
            return foodOrder;
        }

        public void setFoodOrder(FoodOrderDBO foodOrder) {
            this.foodOrder = foodOrder;
        }

        public FoodDBO getFood() {
            return food;
        }

        public void setFood(FoodDBO food) {
            this.food = food;
        }

        public long getFoodOrderDetailsId() {
            return foodOrderDetailsId;
        }

        public void setFoodOrderDetailsId(int foodOrderDetailsId) {
            this.foodOrderDetailsId = foodOrderDetailsId;
        }
    }

创建 FoodOrderDBO 的对象如下:-

try {
            ServingLocationDBO servingLocation=new ServingLocationDBO();
            servingLocation.setLocationId(1);

            FoodDBO foodDBO=new FoodDBO();
            foodDBO.setFoodID(1);

            FoodOrderDBO foodOrderDBO=new FoodOrderDBO();

            Set<FoodOrderDetailsDBO> setFoodOrderDetailsDBO=new HashSet<FoodOrderDetailsDBO>();

            foodOrderDBO.setCustomerId("123456789");
            foodOrderDBO.setFoodOrderId("123456789");
            foodOrderDBO.setPaymentMethod(PaymentMethod.CASH);
            foodOrderDBO.setPurchaseTimeStamp(new Date());
            foodOrderDBO.setPaymentStatus(PaymentStatus.SUCCESS);
            foodOrderDBO.setServingLocation(servingLocation);
            foodOrderDBO.setTotalPrice(95.00);

            FoodOrderDetailsDBO foodOrderDetailsDBO=new FoodOrderDetailsDBO();
            foodOrderDetailsDBO.setFoodQuantity(5);
            foodOrderDetailsDBO.setFood(foodDBO);
            foodOrderDetailsDBO.setFoodOrder(foodOrderDBO);
            setFoodOrderDetailsDBO.add(foodOrderDetailsDBO);

            foodOrderDBO.setSetOfOrderDetails(setFoodOrderDetailsDBO);

            new FoodOrderingDaoImpl().saveFoodOrder(foodOrderDBO);

        } catch (RestClientException e) {
            e.printStackTrace();
        }

将对象插入数据库时​​得到的日志是

2019-01-15 11:23:29 DEBUG SQL:109 - values next value for FOOD_ORDER_DTLS_SEQUENCE
2019-01-15 11:23:29 DEBUG SequenceGenerator:127 - Sequence identifier generated: BasicHolder[java.lang.Integer[-2147474786]]
2019-01-15 11:23:29 DEBUG SQL:109 - values next value for FOOD_ORDER_DTLS_SEQUENCE
2019-01-15 11:23:29 DEBUG SequenceGenerator:127 - Sequence identifier generated: BasicHolder[java.lang.Integer[-2147474785]]
2019-01-15 11:23:29 DEBUG SQL:109 - values next value for FOOD_ORDER_DTLS_SEQUENCE
2019-01-15 11:23:29 DEBUG SequenceGenerator:127 - Sequence identifier generated: BasicHolder[java.lang.Integer[-2147474784]]
2019-01-15 11:23:29 DEBUG SQL:109 - values next value for FOOD_ORDER_DTLS_SEQUENCE
2019-01-15 11:23:29 DEBUG SequenceGenerator:127 - Sequence identifier generated: BasicHolder[java.lang.Integer[-2147474783]]
2019-01-15 11:23:29 DEBUG SQL:109 - values next value for FOOD_ORDER_DTLS_SEQUENCE
2019-01-15 11:23:29 DEBUG SequenceGenerator:127 - Sequence identifier generated: BasicHolder[java.lang.Integer[-2147474782]]

hibernate.properties 文件如下:-

hibernate.connection.driver_class=org.apache.derby.jdbc.ClientDriver
hibernate.connection.url=jdbc:derby://localhost:1527/D://db/foodappdb;create=true;user=food;password=food
hibernate.connection.username=food
hibernate.connection.password=food
hibernate.dialect=org.hibernate.dialect.DerbyTenSevenDialect
hibernate.hbm2ddl.auto=update
hibernate.id.new_generator_mappings=false
show_sql=true

如何阻止这个休眠序列生成进入下一个序列值的无限次评估?

标签: javahibernatejpa

解决方案


推荐阅读