使用自定义复合主键而非@GeneratedValue时能否开启EclipseLink batch-writing
完全可以使用EclipseLink的batch-writing特性,手动赋值复合主键的场景不存在批量写入的兼容障碍。
EclipseLink batch-writing失效的核心限制只来源于需要数据库回写主键值的场景:当使用@GeneratedValue(strategy = GenerationType.IDENTITY)时,每插入一条数据都需要立刻从数据库获取生成的主键值,打断批量执行链路。
你当前使用手动赋值的复合主键,插入前主键值已经确定,不需要从数据库回写任何值,天然满足批量写入的前提条件,甚至比使用序列、表生成主键的场景适配性更好。
检查基础配置是否完整
需在持久化配置中明确开启批量写入,同时指定批量大小:
若使用persistence.xml:<property name="eclipselink.jdbc.batch-writing" value="JDBC"/> <!-- 每攒够指定数量的语句就执行一次批量提交 --> <property name="eclipselink.jdbc.batch-writing.size" value="500"/>若使用Spring Boot:
spring.jpa.properties.eclipselink.jdbc.batch-writing=JDBC spring.jpa.properties.eclipselink.jdbc.batch-writing.size=500另外针对MySQL等数据库,还需要在JDBC连接串中添加参数
rewriteBatchedStatements=true,否则JDBC驱动会默认把批量语句拆分为单条执行。检查事务和flush逻辑
批量写入要求所有待持久化的实体在同一个事务内执行persist,不要每persist一个实体就手动调用flush,也不要开启事务自动提交,攒够批量大小后统一flush/提交事务即可。排除误判场景
EclipseLink默认打印的SQL日志会展示单条INSERT语句,不代表实际没有批量执行,如需验证可以开启JDBC驱动层面的日志,或者统计数据库端实际的请求量确认。
补充:你示例中的
MyIdClass不需要添加@Embeddable注解,该注解仅在使用@EmbeddedId复合主键方案时需要,@IdClass对应的主键类只要实现Serializable接口即可,不过该问题不影响批量写入特性的使用。
内容的提问来源于stack exchange,提问作者payne

