将Spring Batch与嵌入式数据源

时间:2017-11-24 12:33:42

标签: java spring spring-mvc spring-data-jpa spring-batch

我使用Spring Batch与H2等嵌入式存储相结合,获得了奇怪的结果。

以下是我的案例:

我的项目只是常规的Spring Boot微服务。域层具有实体 Model 类,具有瞬态 List 字段。该字段由字节数组字段支持,该字段又不是瞬态的,应该存储。我使用 @PrePersist @PostLoad 序列化和反序列化列表。加载模型后,我清除数组,因此它不会占用内存。

该服务有两个控制器: ModelController AnalyzeController 。他们每个人都执行Spring Batch作业。第一个作业创建Model并将其存储到db中。 db的第二个作业拉模型并用它来计算。

@Entity
@Getter
@Setter
@Table(name = "Model")
@Slf4j
public class Model {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid2")
    @Column(name = "id", length = 36)
    private String id;

    @Transient
    private List<Cluster<ItemPoints>> clusters;

    @Column(columnDefinition = "BYTEA")
    private byte[] serializedClusters;

    //region Serialization / Deserialization 
    @PrePersist
    public void serializeClusters() {
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(out)) {
            oos.writeObject(clusters);
            serializedClusters = out.toByteArray();
        } catch (IOException e) {
            log.error(SERIALIZATION_ERROR_MESSAGE, e);
        }
    }   

    @PostLoad
    @SuppressWarnings("unchecked")
    public void deserializeClusters() {
        try (ByteArrayInputStream in = new ByteArrayInputStream(serializedClusters);
             ObjectInputStream is = new ObjectInputStream(in)) {
            clusters = (List<Cluster<TimeSeriesItemPoints>>) is.readObject();
        } catch (IOException | ClassNotFoundException e) {
            log.error(SERIALIZATION_ERROR_MESSAGE, e);
        }

        // clear serialized data as it is no more needed
        serializedClusters = new byte[]{};
    }
    //endregion
}

存储库层由Spring(CrudRepository)提供

如果我第一次尝试在ModelController之后执行AnalyzeController它按预期工作,但是对存储库的进一步调用返回带有空数组的模型(并且List不会被反序列化)。

这仅适用于嵌入式数据库和单个DataSource(批处理和模型相同)。

如果我使用两个不同的DataSource,它可以正常工作。如果我使用外部数据库,即使使用单个DataSource(例如PostgreSQL)也能正常工作。它也适用于单个数据源而没有Spring Batch。

单个数据源案例的配置:

@Configuration
@Profile("default")
public class DefaultDataSourceConfiguration {
    @Bean
    public DataSource batchDataSource() {
        return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
    }
}

0 个答案:

没有答案