admin管理员组

文章数量:1131559

I have this scheme where I have a header reports table, each report has a set of customers and each customer has a set of products, two one to many relationships.

The thing is my customers and product primary key are composite as shown in the snippets.

My header entity:

@Entity
@Builder
@Getter
@NoArgsConstructor
@Table(name = "samples_report_header")
public class SamplesReportHeaderEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "month", nullable = false)
    private Integer month;

    @Column(name = "year", nullable = false)
    private Integer year;

    @Column(name = "operator", nullable = false)
    private String operator;

    @Column(name = "printed_YN", nullable = false)
    private Character printedYN;

    // One-to-Many relationship with SamplesReportCustomer
    @OneToMany(mappedBy = "reportHeader", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<SamplesReportCustomerEntity> customers = new HashSet<>();

    public SamplesReportHeaderEntity(Long id, Integer month, Integer year, String operator, Character printedYN, Set<SamplesReportCustomerEntity> customers) {
        this.id = id;
        this.month = month;
        this.year = year;
        this.operator = operator;
        this.printedYN = printedYN;
        this.customers = Objects.requireNonNullElseGet(customers, HashSet::new);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "HEADER: {" + this.id + "," + this.month + "," + this.year + "," + this.operator + "}";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        SamplesReportHeaderEntity that = (SamplesReportHeaderEntity) o;
        return id == that.id ;
    }
}

my customer entity:

@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@Table(name = "samples_report_customer")
public class SamplesReportCustomerEntity implements Serializable {

    @EmbeddedId
    private SamplesReportCustomerId id;

    @Column(name = "bem_area")
    private String bemArea;

    @Column(name = "customer_name")
    private String customerName;

    @Column(name = "customer_address")
    private String customerAddress;

    @Column(name = "customer_type")
    private String customerType;

    @Column(name = "visit_feedback")
    private String visitFeedback;

    @Column(name = "visit_date")
    private LocalDate visitDate;

    @Column(name = "attachment")
    private byte[] attachment;

    @Column(name = "mime_type")
    private String mimeType;

    @Column(name = "total_penalty")
    private BigDecimal totalPenalty;

    @Column(name = "jumping_YN")
    private Character jumpingYN;

    @Column(name = "repeated_sales_YN")
    private Character repeatedSalesYN;

    @Column(name = "expensive_items_YN")
    private Character expensiveItemsYN;

    @Column(name = "normal_sales_YN")
    private Character normalSalesYN;

    @Column(name = "product_sales_YN")
    private Character productSalesYN ;

    @Column(name = "sales_quantity")
    private Integer salesQuantity;

    @Column(name = "sales_value")
    private BigDecimal salesValue;

    @Column(name = "bonus_quantity")
    private Integer bonusQuantity;

    @Column(name = "bonus_value")
    private BigDecimal bonusValue;


    // Many-to-One relationship with SamplesReportHeader
    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("reportId")
    @JoinColumn(name = "report_id", referencedColumnName = "id")
    private SamplesReportHeaderEntity reportHeader;

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<SamplesReportProductEntity> products = new HashSet<>();;

    public SamplesReportCustomerEntity(SamplesReportCustomerId id, String bemArea, String customerName, String customerAddress, String customerType, String visitFeedback, LocalDate visitDate, byte[] attachment,String mimeType, BigDecimal totalPenalty, Character jumpingYN, Character repeatedSalesYN, Character expensiveItemsYN,Character normalSalesYN ,Character productSalesYN,  Integer salesQuantity, BigDecimal salesValue, Integer bonusQuantity, BigDecimal bonusValue, SamplesReportHeaderEntity reportHeader, Set<SamplesReportProductEntity> products) {
        this.id = id;
        this.bemArea = bemArea;
        this.customerName = customerName;
        this.customerAddress = customerAddress;
        this.customerType = customerType;
        this.visitFeedback = visitFeedback;
        this.visitDate = visitDate;
        this.attachment = attachment;
        this.mimeType = mimeType;
        this.totalPenalty = totalPenalty;
        this.jumpingYN = jumpingYN;
        this.repeatedSalesYN = repeatedSalesYN;
        this.expensiveItemsYN = expensiveItemsYN;
        this.normalSalesYN = normalSalesYN ;
        this.productSalesYN = productSalesYN;
        this.salesQuantity = salesQuantity;
        this.salesValue = salesValue;
        this.bonusQuantity = bonusQuantity;
        this.bonusValue = bonusValue;
        if(reportHeader == null)
            this.reportHeader = new SamplesReportHeaderEntity();
        else
            this.reportHeader = reportHeader;

        if(products == null)
            this.products = new HashSet<>();
        else
            this.products = products;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SamplesReportCustomerEntity that = (SamplesReportCustomerEntity) o;
        return Objects.equals(id, that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

my customer Id:

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Embeddable
public class SamplesReportCustomerId implements Serializable {

    @NotNull
    @Column(name = "GSK_customer_code", nullable = false)
    private String GSKCustomerCode;

    @NotNull
    @Column(name = "report_id", nullable = false)
    private Long reportId;

    @NotNull
    @Column(name = "distributor_customer_code", nullable = false)
    private String distributorCustomerCode;

    @NotNull
    @Column(name = "distributor_code", nullable = false)
    private String distributorCode;


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SamplesReportCustomerId that = (SamplesReportCustomerId) o;
        return Objects.equals(GSKCustomerCode, that.GSKCustomerCode) &&
                Objects.equals(reportId, that.reportId) &&
               Objects.equals(distributorCode,that.distributorCode) &&
               Objects.equals(distributorCustomerCode,that.distributorCustomerCode);
    }
    @Override
    public int hashCode() {
        return Objects.hash(GSKCustomerCode, reportId , distributorCode , distributorCustomerCode);
    }
}

my product entity:

@Entity
@Builder
@Data
@NoArgsConstructor
@Table(name = "samples_report_product")
public class SamplesReportProductEntity implements Serializable {

    @EmbeddedId
    private SamplesReportProductId id ;

    @Column(name = "brand")
    private String brand;

    @Column(name = "item_description")
    private String itemDescription;

    @Column(name = "gsk_item_code")
    private String GSKItemCode;

    @Column(name = "sales_quantity")
    private Integer salesQuantity;

    @Column(name = "sales_value")
    private BigDecimal salesValue;

    @Column(name = "bonus_quantity")
    private Integer bonusQuantity;

    @Column(name = "bonus_value")
    private BigDecimal bonusValue;


    @Column(name = "visit_feedback")
    private String visitFeedback;

    @Column(name = "visit_date")
    private LocalDate visitDate;

    @Column(name = "penalty1")
    private BigDecimal penalty1;

    @Column(name = "penalty2")
    private BigDecimal penalty2;

    @Column(name = "penalty3")
    private BigDecimal penalty3;

    @Column(name = "total_penalty")
    private BigDecimal totalPenalty;

    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "GSK_customer_code", referencedColumnName = "GSK_customer_code",nullable = false,insertable = false, updatable = false),
            @JoinColumn(name = "report_id", referencedColumnName = "report_id", nullable = false,insertable = false, updatable = false) ,
            @JoinColumn(name = "distributor_code", referencedColumnName = "distributor_code",nullable = false,insertable = false, updatable = false) ,
            @JoinColumn(name = "distributor_customer_code", referencedColumnName = "distributor_customer_code",nullable = false,insertable = false, updatable = false)
    })
    private SamplesReportCustomerEntity customer;


    public SamplesReportProductEntity(SamplesReportProductId id,String brand, String itemDescription, String GSKItemCode, Integer salesQuantity, BigDecimal salesValue, Integer bonusQuantity, BigDecimal bonusValue, String visitFeedback, LocalDate visitDate, BigDecimal penalty1, BigDecimal penalty2, BigDecimal penalty3, BigDecimal totalPenalty, SamplesReportCustomerEntity customer) {
        this.id = id;
        this.brand = brand;
        this.itemDescription = itemDescription;
        this.GSKItemCode = GSKItemCode;
        this.salesQuantity = salesQuantity;
        this.salesValue = salesValue;
        this.bonusQuantity = bonusQuantity;
        this.bonusValue = bonusValue;
        this.visitFeedback = visitFeedback;
        this.visitDate = visitDate;
        this.penalty1 = penalty1;
        this.penalty2 = penalty2;
        this.penalty3 = penalty3;
        this.totalPenalty = totalPenalty;
        if(customer == null)
            this.customer = new SamplesReportCustomerEntity();
        else
            this.customer = customer;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SamplesReportProductEntity that = (SamplesReportProductEntity) o;
        return Objects.equals(id, that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

my product Id:

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SamplesReportProductId implements Serializable {

    @NotNull
    @Column(name = "distributor_code", nullable = false)
    private String distributorCode;

    @NotNull
    @Column(name = "distributor_customer_code", nullable = false)
    private String distributorCustomerCode;

    @NotNull
    @Column(name = "distributor_invoice_id", nullable = false)
    private String distributorInvoiceId;

    @NotNull
    @Column(name = "sales_type", nullable = false)
    private String salesType;

    @NotNull
    @Column(name = "distributor_item_code", nullable = false)
    private String distributorItemCode;

    @NotNull
    @Column(name = "batch_code", nullable = false)
    private String batchCode;

    @NotNull
    @Column(name = "distributor_invoice_date", nullable = false)
    private LocalDateTime distributorInvoiceDate;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SamplesReportProductId that = (SamplesReportProductId) o;
        return Objects.equals(distributorCode, that.distributorCode) &&
                Objects.equals(distributorCustomerCode, that.distributorCustomerCode) &&
                Objects.equals(distributorInvoiceId, that.distributorInvoiceId) &&
                Objects.equals(salesType, that.salesType) &&
                Objects.equals(distributorItemCode, that.distributorItemCode) &&
                Objects.equals(batchCode, that.batchCode) &&
                Objects.equals(distributorInvoiceDate, that.distributorInvoiceDate);
    }
    @Override
    public int hashCode() {
        return Objects.hash(distributorCode, distributorCustomerCode, distributorInvoiceId, salesType, distributorItemCode, batchCode, distributorInvoiceDate);
    }
}

I am trying to populate these tables from a denormalized history table, where I am creating an report entity add a customer to its customer set and add the product to the customer's product set something like this:

for (var record : bemHistoryEntities) {
                String operator = record.getOperator();
                String gskCustomerCode = record.getGskCustomerCode();
                String distCustCode = record.getDistributorCustomerCode();
                String distCode = record.getDistributorCode();

                // getting the report header
                List<SamplesReportHeaderEntity> headersList = headerEntities.stream().filter(entity ->
                                (entity.getMonth() == month && entity.getYear() == year && operator.equals(entity.getOperator())))
                        .collect(Collectors.toList());
                SamplesReportHeaderEntity headerEntity = null;

                // header coming from the db
                if (headersList.size() > 0) {
                    headerEntity = headersList.get(0);
                } else {
                    // if not persisted before, create it
                    headerEntity = samplesReportHeaderRepository.save(new SamplesReportHeaderEntity().builder()
                            .operator(operator)
                            .month(month)
                            .year(year)
                            .printedYN('N')
                            .build());
                    headerEntities.add(headerEntity);
                }
                
                // creating samples customer from the record
                SamplesReportCustomerEntity customer = new SamplesReportCustomerEntity().builder()
                        .id(new SamplesReportCustomerId(gskCustomerCode, headerEntity.getId(), distCustCode, distCode))
                        .bemArea(record.getBemArea())
                        .customerAddress(record.getDistributorCustomerAddress())
                        .customerName(record.getDistributorCustomerName())
                        .customerType(record.getBemCustomerType())
                        .jumpingYN(intermediateEntityMap.get(gskCustomerCode).getJumpingYN())
                        .repeatedSalesYN(intermediateEntityMap.get(gskCustomerCode).getRepeatedYN())
                        .expensiveItemsYN(intermediateEntityMap.get(gskCustomerCode).getExpensiveYN())
                        .productSalesYN(intermediateEntityMap.get(gskCustomerCode).getProductYN())
                        .normalSalesYN(intermediateEntityMap.get(gskCustomerCode).getNormalYN())
                        .build();

                // creating samples product from the record to the created customer
                SamplesReportProductEntity product = new SamplesReportProductEntity().builder()
                        .id(new SamplesReportProductId(distCode, distCustCode, record.getInvoiceNumber(), record.getSalesType(), record.getDistributorItemCode(), record.getBatchCode(), record.getInvoiceDate()))
                        .brand(record.getBrand())
                        .itemDescription(record.getGskItemDescription())
                        .GSKItemCode(record.getGskItemCode())
                        .build();

                customer.getProducts().add(product);
                headerEntity.getCustomers().add(customer);
            }

Everything is okay until the commit phase starts, it always tries to insert a row to the report header table which I no way created it and even if I printed the content of the persistence context it wasn't there also, and of course it violates the non-null constraints making the whole transaction to fail.

Detail: Failing row contains (70, null, null, null, null).

persistence context after the function execution:
Entity in context: HEADER: {67,10,2024,Hossam}
Entity in context: HEADER: {66,10,2024,Vacant}
Entity in context: HEADER: {69,10,2024,Samir}
Entity in context: HEADER: {68,10,2024,Saad}

I have debugged the the whole function's execution, but the commitTransactionAfterReturning function always throws the above error.

I have this scheme where I have a header reports table, each report has a set of customers and each customer has a set of products, two one to many relationships.

The thing is my customers and product primary key are composite as shown in the snippets.

My header entity:

@Entity
@Builder
@Getter
@NoArgsConstructor
@Table(name = "samples_report_header")
public class SamplesReportHeaderEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "month", nullable = false)
    private Integer month;

    @Column(name = "year", nullable = false)
    private Integer year;

    @Column(name = "operator", nullable = false)
    private String operator;

    @Column(name = "printed_YN", nullable = false)
    private Character printedYN;

    // One-to-Many relationship with SamplesReportCustomer
    @OneToMany(mappedBy = "reportHeader", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<SamplesReportCustomerEntity> customers = new HashSet<>();

    public SamplesReportHeaderEntity(Long id, Integer month, Integer year, String operator, Character printedYN, Set<SamplesReportCustomerEntity> customers) {
        this.id = id;
        this.month = month;
        this.year = year;
        this.operator = operator;
        this.printedYN = printedYN;
        this.customers = Objects.requireNonNullElseGet(customers, HashSet::new);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "HEADER: {" + this.id + "," + this.month + "," + this.year + "," + this.operator + "}";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        SamplesReportHeaderEntity that = (SamplesReportHeaderEntity) o;
        return id == that.id ;
    }
}

my customer entity:

@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@Table(name = "samples_report_customer")
public class SamplesReportCustomerEntity implements Serializable {

    @EmbeddedId
    private SamplesReportCustomerId id;

    @Column(name = "bem_area")
    private String bemArea;

    @Column(name = "customer_name")
    private String customerName;

    @Column(name = "customer_address")
    private String customerAddress;

    @Column(name = "customer_type")
    private String customerType;

    @Column(name = "visit_feedback")
    private String visitFeedback;

    @Column(name = "visit_date")
    private LocalDate visitDate;

    @Column(name = "attachment")
    private byte[] attachment;

    @Column(name = "mime_type")
    private String mimeType;

    @Column(name = "total_penalty")
    private BigDecimal totalPenalty;

    @Column(name = "jumping_YN")
    private Character jumpingYN;

    @Column(name = "repeated_sales_YN")
    private Character repeatedSalesYN;

    @Column(name = "expensive_items_YN")
    private Character expensiveItemsYN;

    @Column(name = "normal_sales_YN")
    private Character normalSalesYN;

    @Column(name = "product_sales_YN")
    private Character productSalesYN ;

    @Column(name = "sales_quantity")
    private Integer salesQuantity;

    @Column(name = "sales_value")
    private BigDecimal salesValue;

    @Column(name = "bonus_quantity")
    private Integer bonusQuantity;

    @Column(name = "bonus_value")
    private BigDecimal bonusValue;


    // Many-to-One relationship with SamplesReportHeader
    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("reportId")
    @JoinColumn(name = "report_id", referencedColumnName = "id")
    private SamplesReportHeaderEntity reportHeader;

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<SamplesReportProductEntity> products = new HashSet<>();;

    public SamplesReportCustomerEntity(SamplesReportCustomerId id, String bemArea, String customerName, String customerAddress, String customerType, String visitFeedback, LocalDate visitDate, byte[] attachment,String mimeType, BigDecimal totalPenalty, Character jumpingYN, Character repeatedSalesYN, Character expensiveItemsYN,Character normalSalesYN ,Character productSalesYN,  Integer salesQuantity, BigDecimal salesValue, Integer bonusQuantity, BigDecimal bonusValue, SamplesReportHeaderEntity reportHeader, Set<SamplesReportProductEntity> products) {
        this.id = id;
        this.bemArea = bemArea;
        this.customerName = customerName;
        this.customerAddress = customerAddress;
        this.customerType = customerType;
        this.visitFeedback = visitFeedback;
        this.visitDate = visitDate;
        this.attachment = attachment;
        this.mimeType = mimeType;
        this.totalPenalty = totalPenalty;
        this.jumpingYN = jumpingYN;
        this.repeatedSalesYN = repeatedSalesYN;
        this.expensiveItemsYN = expensiveItemsYN;
        this.normalSalesYN = normalSalesYN ;
        this.productSalesYN = productSalesYN;
        this.salesQuantity = salesQuantity;
        this.salesValue = salesValue;
        this.bonusQuantity = bonusQuantity;
        this.bonusValue = bonusValue;
        if(reportHeader == null)
            this.reportHeader = new SamplesReportHeaderEntity();
        else
            this.reportHeader = reportHeader;

        if(products == null)
            this.products = new HashSet<>();
        else
            this.products = products;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SamplesReportCustomerEntity that = (SamplesReportCustomerEntity) o;
        return Objects.equals(id, that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

my customer Id:

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Embeddable
public class SamplesReportCustomerId implements Serializable {

    @NotNull
    @Column(name = "GSK_customer_code", nullable = false)
    private String GSKCustomerCode;

    @NotNull
    @Column(name = "report_id", nullable = false)
    private Long reportId;

    @NotNull
    @Column(name = "distributor_customer_code", nullable = false)
    private String distributorCustomerCode;

    @NotNull
    @Column(name = "distributor_code", nullable = false)
    private String distributorCode;


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SamplesReportCustomerId that = (SamplesReportCustomerId) o;
        return Objects.equals(GSKCustomerCode, that.GSKCustomerCode) &&
                Objects.equals(reportId, that.reportId) &&
               Objects.equals(distributorCode,that.distributorCode) &&
               Objects.equals(distributorCustomerCode,that.distributorCustomerCode);
    }
    @Override
    public int hashCode() {
        return Objects.hash(GSKCustomerCode, reportId , distributorCode , distributorCustomerCode);
    }
}

my product entity:

@Entity
@Builder
@Data
@NoArgsConstructor
@Table(name = "samples_report_product")
public class SamplesReportProductEntity implements Serializable {

    @EmbeddedId
    private SamplesReportProductId id ;

    @Column(name = "brand")
    private String brand;

    @Column(name = "item_description")
    private String itemDescription;

    @Column(name = "gsk_item_code")
    private String GSKItemCode;

    @Column(name = "sales_quantity")
    private Integer salesQuantity;

    @Column(name = "sales_value")
    private BigDecimal salesValue;

    @Column(name = "bonus_quantity")
    private Integer bonusQuantity;

    @Column(name = "bonus_value")
    private BigDecimal bonusValue;


    @Column(name = "visit_feedback")
    private String visitFeedback;

    @Column(name = "visit_date")
    private LocalDate visitDate;

    @Column(name = "penalty1")
    private BigDecimal penalty1;

    @Column(name = "penalty2")
    private BigDecimal penalty2;

    @Column(name = "penalty3")
    private BigDecimal penalty3;

    @Column(name = "total_penalty")
    private BigDecimal totalPenalty;

    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "GSK_customer_code", referencedColumnName = "GSK_customer_code",nullable = false,insertable = false, updatable = false),
            @JoinColumn(name = "report_id", referencedColumnName = "report_id", nullable = false,insertable = false, updatable = false) ,
            @JoinColumn(name = "distributor_code", referencedColumnName = "distributor_code",nullable = false,insertable = false, updatable = false) ,
            @JoinColumn(name = "distributor_customer_code", referencedColumnName = "distributor_customer_code",nullable = false,insertable = false, updatable = false)
    })
    private SamplesReportCustomerEntity customer;


    public SamplesReportProductEntity(SamplesReportProductId id,String brand, String itemDescription, String GSKItemCode, Integer salesQuantity, BigDecimal salesValue, Integer bonusQuantity, BigDecimal bonusValue, String visitFeedback, LocalDate visitDate, BigDecimal penalty1, BigDecimal penalty2, BigDecimal penalty3, BigDecimal totalPenalty, SamplesReportCustomerEntity customer) {
        this.id = id;
        this.brand = brand;
        this.itemDescription = itemDescription;
        this.GSKItemCode = GSKItemCode;
        this.salesQuantity = salesQuantity;
        this.salesValue = salesValue;
        this.bonusQuantity = bonusQuantity;
        this.bonusValue = bonusValue;
        this.visitFeedback = visitFeedback;
        this.visitDate = visitDate;
        this.penalty1 = penalty1;
        this.penalty2 = penalty2;
        this.penalty3 = penalty3;
        this.totalPenalty = totalPenalty;
        if(customer == null)
            this.customer = new SamplesReportCustomerEntity();
        else
            this.customer = customer;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SamplesReportProductEntity that = (SamplesReportProductEntity) o;
        return Objects.equals(id, that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

my product Id:

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SamplesReportProductId implements Serializable {

    @NotNull
    @Column(name = "distributor_code", nullable = false)
    private String distributorCode;

    @NotNull
    @Column(name = "distributor_customer_code", nullable = false)
    private String distributorCustomerCode;

    @NotNull
    @Column(name = "distributor_invoice_id", nullable = false)
    private String distributorInvoiceId;

    @NotNull
    @Column(name = "sales_type", nullable = false)
    private String salesType;

    @NotNull
    @Column(name = "distributor_item_code", nullable = false)
    private String distributorItemCode;

    @NotNull
    @Column(name = "batch_code", nullable = false)
    private String batchCode;

    @NotNull
    @Column(name = "distributor_invoice_date", nullable = false)
    private LocalDateTime distributorInvoiceDate;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SamplesReportProductId that = (SamplesReportProductId) o;
        return Objects.equals(distributorCode, that.distributorCode) &&
                Objects.equals(distributorCustomerCode, that.distributorCustomerCode) &&
                Objects.equals(distributorInvoiceId, that.distributorInvoiceId) &&
                Objects.equals(salesType, that.salesType) &&
                Objects.equals(distributorItemCode, that.distributorItemCode) &&
                Objects.equals(batchCode, that.batchCode) &&
                Objects.equals(distributorInvoiceDate, that.distributorInvoiceDate);
    }
    @Override
    public int hashCode() {
        return Objects.hash(distributorCode, distributorCustomerCode, distributorInvoiceId, salesType, distributorItemCode, batchCode, distributorInvoiceDate);
    }
}

I am trying to populate these tables from a denormalized history table, where I am creating an report entity add a customer to its customer set and add the product to the customer's product set something like this:

for (var record : bemHistoryEntities) {
                String operator = record.getOperator();
                String gskCustomerCode = record.getGskCustomerCode();
                String distCustCode = record.getDistributorCustomerCode();
                String distCode = record.getDistributorCode();

                // getting the report header
                List<SamplesReportHeaderEntity> headersList = headerEntities.stream().filter(entity ->
                                (entity.getMonth() == month && entity.getYear() == year && operator.equals(entity.getOperator())))
                        .collect(Collectors.toList());
                SamplesReportHeaderEntity headerEntity = null;

                // header coming from the db
                if (headersList.size() > 0) {
                    headerEntity = headersList.get(0);
                } else {
                    // if not persisted before, create it
                    headerEntity = samplesReportHeaderRepository.save(new SamplesReportHeaderEntity().builder()
                            .operator(operator)
                            .month(month)
                            .year(year)
                            .printedYN('N')
                            .build());
                    headerEntities.add(headerEntity);
                }
                
                // creating samples customer from the record
                SamplesReportCustomerEntity customer = new SamplesReportCustomerEntity().builder()
                        .id(new SamplesReportCustomerId(gskCustomerCode, headerEntity.getId(), distCustCode, distCode))
                        .bemArea(record.getBemArea())
                        .customerAddress(record.getDistributorCustomerAddress())
                        .customerName(record.getDistributorCustomerName())
                        .customerType(record.getBemCustomerType())
                        .jumpingYN(intermediateEntityMap.get(gskCustomerCode).getJumpingYN())
                        .repeatedSalesYN(intermediateEntityMap.get(gskCustomerCode).getRepeatedYN())
                        .expensiveItemsYN(intermediateEntityMap.get(gskCustomerCode).getExpensiveYN())
                        .productSalesYN(intermediateEntityMap.get(gskCustomerCode).getProductYN())
                        .normalSalesYN(intermediateEntityMap.get(gskCustomerCode).getNormalYN())
                        .build();

                // creating samples product from the record to the created customer
                SamplesReportProductEntity product = new SamplesReportProductEntity().builder()
                        .id(new SamplesReportProductId(distCode, distCustCode, record.getInvoiceNumber(), record.getSalesType(), record.getDistributorItemCode(), record.getBatchCode(), record.getInvoiceDate()))
                        .brand(record.getBrand())
                        .itemDescription(record.getGskItemDescription())
                        .GSKItemCode(record.getGskItemCode())
                        .build();

                customer.getProducts().add(product);
                headerEntity.getCustomers().add(customer);
            }

Everything is okay until the commit phase starts, it always tries to insert a row to the report header table which I no way created it and even if I printed the content of the persistence context it wasn't there also, and of course it violates the non-null constraints making the whole transaction to fail.

Detail: Failing row contains (70, null, null, null, null).

persistence context after the function execution:
Entity in context: HEADER: {67,10,2024,Hossam}
Entity in context: HEADER: {66,10,2024,Vacant}
Entity in context: HEADER: {69,10,2024,Samir}
Entity in context: HEADER: {68,10,2024,Saad}

I have debugged the the whole function's execution, but the commitTransactionAfterReturning function always throws the above error.

Share Improve this question asked Jan 7 at 19:46 Marwan EmadMarwan Emad 11 bronze badge 1
  • Is there some way to print every record that gets processed to the one with the odd 70? Since that isn't coming from a ghost-in-the-machine, there is very likely a bad record somewhere. – Paul T. Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 0

It turned out that I was not setting the report header in the customer entity and the customer in the product entity when I am creating them.

本文标签: javaHibernate inserting an unexpected rowStack Overflow