无法使用休眠模式执行批量插入

时间:2018-11-18 15:41:13

标签: hibernate spring-boot jpa spring-data-jpa

我需要使用SpringBoot服务将excel的大约100,000行插入MySQL。这必须是用户上传excel的功能,然后我们才能存储记录。

当我不使用休眠批处理插入时,我可以插入记录,但是要花很多时间,因此我尝试使用休眠模式进行批处理插入。

以下是我的文件:

实体/模型:

@Entity
@Table(name="tariff")
public class Tariff implements Serializable {

    @Id
    @Column(name="tariff_id")
    private Long tariffId;

    @Column(name="provider_id")
    private String providerId;

    @Column(name="insurer_id")
    private String insurerId;

    @ManyToOne
    @JoinColumn(name="tariff_type_id", referencedColumnName = "tariff_type_id")
    private TariffType tariffType;

    @ManyToOne
    @JoinColumn(name="billing_group_id", referencedColumnName = "billing_group_id")
    private BillingGroup billingGroup;

    @ManyToOne
    @JoinColumn(name="billing_sub_group_id", referencedColumnName = "billing_sub_group_id")
    private BillingSubGroup billingSubGroup;

    @ManyToOne
    @JoinColumn(name="room_type_id", referencedColumnName = "room_type_id")
    private RoomType roomType;

    @ManyToOne
    @JoinColumn(name="room_category_id", referencedColumnName = "room_category_id")
    private RoomCategory roomCategory;

    @NotNull
    @Column(name="billing_code")
    private String billingCode;

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

    @NotNull
    @Column(name="tariff_rate")
    private Double tariffRate;

    @Column(name="tariff_system")
    private String tariffSystem;

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

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

    @Column(name="tariff_year")
    private String tariffYear;
}

resources / META-INF / persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence

http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="project_persistence" transaction-type="RESOURCE_LOCAL">
    <!-- enable if you want xml mappings
    <mapping-file>META-INF/orm.xml</mapping-file>
    -->
    <properties>
        <!-- Configuring JDBC properties -->
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/databasename"/>
        <property name="javax.persistence.jdbc.user" value="root"/>
        <property name="javax.persistence.jdbc.password" value=""/>

        <!-- Hibernate properties -->
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
        <property name="hibernate.hbm2ddl.auto" value="update"/>
        <property name="hibernate.format_sql" value="true"/>
        <property name="hibernate.show_sql" value="true"/>

        <!-- batching size -->
        <property name="hibernate.jdbc.batch_size" value="500"/>
        <property name="hibernate.order_inserts" value="true"/>
        <property name="hibernate.order_updates" value="true"/>
        <property name="hibernate.jdbc.batch_versioned_data" value="true"/>

    </properties>
</persistence-unit>

我正在执行批量插入的功能:

private void saveTariffsFromExcel(DataFormatter dataFormatter, Sheet sheet, int totalRows, TariffType tariffType) {

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("project_persistence");
    EntityManager em = emf.createEntityManager();
    em.setFlushMode(FlushModeType.COMMIT);

    BillingGroup billingGroup;
    BillingSubGroup billingSubGroup;
    RoomCategory roomCategory;
    RoomType roomType;
    Tariff tariff;

    Long tariffId = tariffRepository.count()+1;

    int batchSize = 500;

    for (int i = 1; i < totalRows; i++) {

        tariff = new Tariff();
        Row row = sheet.getRow(i);

        String tariffTypeStr = dataFormatter.formatCellValue(row.getCell(TARIFF_TYPE));
        String billingCodeStr = dataFormatter.formatCellValue(row.getCell(BILLING_CODE));
        String billingGroupStr = dataFormatter.formatCellValue(row.getCell(BILLING_GROUP));
        String billingSubGroupStr = dataFormatter.formatCellValue(row.getCell(BILLING_SUB_GROUP));
        String system = dataFormatter.formatCellValue(row.getCell(SYSTEM));
        String description = dataFormatter.formatCellValue(row.getCell(DESCRIPTION));
        String inclusions = dataFormatter.formatCellValue(row.getCell(INCLUSIONS));
        String exclusions = dataFormatter.formatCellValue(row.getCell(EXCLUSIONS));
        String roomTypeStr = dataFormatter.formatCellValue(row.getCell(ROOM_TYPE));
        String roomCategoryStr = dataFormatter.formatCellValue(row.getCell(ROOM_CATEGORY));

        String tariffRate = dataFormatter.formatCellValue(row.getCell(TARIFF));

        tariff.setTariffId(tariffId);

        if (tariffTypeStr != null && tariffTypeStr != "") {
            tariffType.setTariffType(tariffTypeStr);
            tariff.setTariffType(tariffType);
        }

        if (billingGroupStr != null && billingGroupStr != "") {
            billingGroup = billingGroupRepository.getByBillingGroup(billingGroupStr);
            tariff.setBillingGroup(billingGroup);
        }

        if (billingSubGroupStr != null && billingSubGroupStr != "") {
            billingSubGroup = billingSubGroupRepository.getByBillingSubGroup(billingSubGroupStr);
            tariff.setBillingSubGroup(billingSubGroup);
        }

        if (roomTypeStr != null && roomTypeStr != "") {
            roomType = roomTypeRepository.getByRoomType(roomTypeStr);
            tariff.setRoomType(roomType);
        }

        if (roomCategoryStr != null && roomCategoryStr != "") {
            roomCategory = roomCategoryRepository.getByRoomCategory(roomCategoryStr);
            tariff.setRoomCategory(roomCategory);
        }

        if (billingCodeStr != null && billingCodeStr != "") {
            tariff.setBillingCode(billingCodeStr);
        }

        if (description != null && description != "") {
            tariff.setDescription(description);
        }

        if (system != null && system != "") {
            tariff.setTariffSystem(system);
        }

        if (tariffRate.isEmpty() || tariffRate == "") {
            continue;
        }

        tariff.setTariffRate(Double.parseDouble(tariffRate));


        if (inclusions != null && inclusions != "") {
            tariff.setInclusion(inclusions);
        }

        if (exclusions != null && exclusions != "") {
            tariff.setExclusion(exclusions);
        }
        tariff.setTariffYear("2018");       

        em.persist(tariff);
        if (i % batchSize == 0 && i > 0) {
            em.flush();
            em.clear();
        }
        tariffId++;
    }
    em.getTransaction().commit();
}

但是,在第一次调用持久化时会导致以下错误:

  

org.hibernate.property.access.spi.PropertyAccessException:通过反射访问持久性[com.project.model.tariff]字段而访问字段[private java.lang.Long com.project.model.tariff.Tariff.tariffId]时出错.Tariff#tariffId]

控制台日志显示:

  

原因:java.lang.IllegalArgumentException:无法将java.lang.Long字段com.project.model.tariff.Tariff.tariffId设置为com.project.model.tariff.Tariff

我正在使用的版本: 弹簧靴:2.0.4 HibernateCore:5.2.17

我尝试搜索此错误,并通过了很多SO和博客链接,但是都没有运气。我对休眠很陌生。因此,任何参考或指导都将有所帮助。

0 个答案:

没有答案