- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
前面的信息。我只是选择了我认为必要的代码片段,它们位于不同的文件中,所以不要怀疑它看起来是否有点困惑。
在我的 SpringBatch Reader 作业中,我正在读取一个平面文件。我编写了一个从 FieldSetMapper 调用的 ProductValueMapper,它将列映射到 Hibernate 模型。该映射器还检查产品是否已存在于数据库中,如果存在,则使用数据库中的实体,否则将创建一个新实体。
@Component
@StepScope
public class ProductValueMapper {
@Autowired
private IProductDao productDao;
@Autowired
private IFactory<Product> productFactory;
private Product fetch(String[] criteria) {
//... try to fetch product using different criteria, or create a new one using the factory ...
return product;
}
Product map(String[] criteria) {
Product product = fetch(criteria);
//... map some stuff ...
return product;
}
DAO 获取实体管理器由
Autowiring@PersistenceContext
private EntityManager manager;
并被标记为@Transactional
然后我有一个处理器,除了记录之外什么都不做。
然后我写入默认的 jpaItemWriter 是这样创建的:
@Configuration
@Import(DatabaseConfiguration.class)
public class HibernateConfiguration extends DefaultBatchConfigurer {
@Autowired
@Qualifier("oracleDataSource")
private DataSource dataSource;
@Bean(name = "jpaEntitiyManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPersistenceUnitName("hibernatePersistenceUnit");
em.setPackagesToScan("com.somepackage");
em.setDataSource(dataSource);
em.setJpaProperties(hibernateProperties());
HibernateJpaVendorAdapter vendor = new HibernateJpaVendorAdapter();
vendor.setGenerateDdl(false);
vendor.setShowSql(true);
em.setJpaVendorAdapter(vendor);
return em;
}
@Bean
public Properties hibernateProperties() {
Properties prop = new Properties();
prop.setProperty("hibernate.hbm2ddl.auto", "validate");
prop.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
prop.setProperty("hibernate.globally_quoted_identifiers", "false");
prop.setProperty("hibernate.show_sql", "true");
return prop;
}
@Override
public PlatformTransactionManager getTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
@Configuration
@EnableBatchProcessing(modular = true)
@ComponentScan({"com.somepackage"})
@Import({HibernateConfiguration.class, DatabaseConfiguration.class})
public class BatchConfiguration {
@Autowired
public EntityManagerFactory emf;
@Bean
public JpaItemWriter<ProductEntity> jpaItemWriter() {
JpaItemWriter<ProductEntity> itemWriter = new JpaItemWriter<>();
itemWriter.setEntityManagerFactory(emf);
return itemWriter;
}
//... rest of the setup for the job
}
程序按预期工作,除了 block 大小 > 1 和一个项目在批处理期间发生更改,我遇到了 hibernate 在选择以下项目期间执行更新语句的问题。
我知道我可以通过在处理器中调用 flush 和 save 或将 block 大小减小到 1 来解决这个问题,但不知何故,这两种解决方案对我来说都是错误的。不应该每个项目都有一个交易保持打开状态,然后在调用作者时应该一个一个地提交这些交易吗?还是我理解错了Spring Batch中transactionHandling的原理。
* 编辑 1 *
问题在于,当将 block 大小设置为 1 时,程序会按预期运行:更新发生在写入阶段。
2016-09-05 11:20:40.828 INFO 11084 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - beforeRead
2016-09-05 11:20:40.828 INFO 11084 --- [ main] n.e.p.i.r.map.GenericProductMapper : Processing product: Prduct1
Hibernate: select productent0_.PRODUCTSN as PRODUCTSN1_25_, .....
2016-09-05 11:20:40.832 INFO 11084 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - afterRead: com.somepackage.ProductEntity@8e654f7
2016-09-05 11:20:40.832 INFO 11084 --- [ main] n.e.p.i.logging.LogItemWriterListener : ItemWriteListener - beforeWrite
Hibernate: update PIME.PRODUCT set AVAILABILITYDATE=?, ....
2016-09-05 11:20:40.836 INFO 11084 --- [ main] n.e.p.i.logging.LogItemWriterListener : ItemWriteListener - afterWrite
2016-09-05 11:20:40.887 INFO 11084 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - beforeRead
2016-09-05 11:20:40.887 INFO 11084 --- [ main] n.e.p.i.r.map.GenericProductMapper : Processing product: Product2
Hibernate: select productent0_.PRODUCTSN as PRODUCTSN1_25_, ....
2016-09-05 11:20:40.891 INFO 11084 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - afterRead: com.somepackage.ProductEntity@2c7fb24c
2016-09-05 11:20:40.891 INFO 11084 --- [ main] n.e.p.i.logging.LogItemWriterListener : ItemWriteListener - beforeWrite
2016-09-05 11:20:40.891 INFO 11084 --- [ main] n.e.p.i.logging.LogItemWriterListener : ItemWriteListener - afterWrite
但是当 block 大小增加时,写入会以 select 语句的形式发生,因为写入不是在处理产品结束时发生,而是在 block 中发生:
2016-09-05 11:09:36.240 INFO 12408 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - beforeRead
2016-09-05 11:09:36.240 INFO 12408 --- [ main] n.e.p.i.r.map.GenericProductMapper : Processing product: Product1
Hibernate: select productent0_.PRODUCTSN as PRODUCTSN1_25_, ....
2016-09-05 11:09:36.244 INFO 12408 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - afterRead: com.somemodule.ProductEntity@6f28a07e
2016-09-05 11:09:36.244 INFO 12408 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - beforeRead
2016-09-05 11:09:36.244 INFO 12408 --- [ main] n.e.p.i.r.map.GenericProductMapper : Processing product: Product2
Hibernate: update PIME.PRODUCT set AVAILABILITYDATE=?, ....
Hibernate: select productent0_.PRODUCTSN as PRODUCTSN1_25_, ....
2016-09-05 11:09:36.250 INFO 12408 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - afterRead: com.somemodule.ProductEntity@71852f76
2016-09-05 11:09:36.250 INFO 12408 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - beforeRead
2016-09-05 11:09:36.250 INFO 12408 --- [ main] n.e.p.i.r.map.GenericProductMapper : Processing product: Product3
Hibernate: select productent0_.PRODUCTSN as PRODUCTSN1_25_, ....
2016-09-05 11:09:36.253 INFO 12408 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - afterRead: com.somemodule.ProductEntity@76ac8c3d
2016-09-05 11:09:36.253 INFO 12408 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - beforeRead
2016-09-05 11:09:36.253 INFO 12408 --- [ main] n.e.p.i.r.map.GenericProductMapper : Processing product: Product4
Hibernate: select productent0_.PRODUCTSN as PRODUCTSN1_25_, ....
2016-09-05 11:09:36.256 INFO 12408 --- [ main] n.e.p.i.logging.LogItemReadListener : ItemReadListener - afterRead: com.somemodule.ProductEntity@6a0d47e8
2016-09-05 11:09:36.256 INFO 12408 --- [ main] n.e.p.i.logging.LogItemWriterListener : ItemWriteListener - beforeWrite
2016-09-05 11:09:36.257 INFO 12408 --- [ main] n.e.p.i.logging.LogItemWriterListener : ItemWriteListener - afterWrite
最佳答案
我们需要使用 Entry 而不是 Entity。在这种情况下,最好的做法是
否则,Spring 将执行如下操作:
注意:如果你不希望它发生,你可以使用@ReadOnly 和@Transactional
谢谢,义亚
关于java - Spring batch + hibernate 在选择期间写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39289159/
我有这个代码 var myChart = new FusionCharts("../themes/clean/charts/hbullet.swf", "myChartId", "400", "75
既然写入是立即进行的(复制到内核缓冲区并返回),那么使用 io_submit 进行写入有什么好处? 事实上,它 (aio/io_submit) 看起来更糟,因为您必须在堆上分配写入缓冲区并且不能使用基
我正在使用 mootool 的 Request.JSON 从 Twitter 检索推文。收到它后,我将写入目标 div 的 .innerHTML 属性。当我在本地将其作为文件进行测试时,即 file:
最终,我想将 Vertica DB 中的数据抓取到 Spark 中,训练机器学习模型,进行预测,并将这些预测存储到另一个 Vertica DB 中。 当前的问题是确定流程最后部分的瓶颈:将 Spark
我使用 WEKA 库编写了一个 Java 程序, 训练分类算法 使用经过训练的算法对未标记的数据集运行预测 将结果写入 .csv 文件 问题在于它当前写出离散分类结果(即算法猜测一行属于哪个类别)。我
背景 - 我正在考虑使用 clickonce 通过 clickonce(通过网站)部署 WinForms 应用程序。相对简单的应用程序的要素是: - 它是一个可执行文件和一个数据库文件(sqlite)
是否有更好的解决方案来快速初始化 C 数组(在堆上创建)?就像我们使用大括号一样 double** matrix_multiply(const double **l_matrix, const dou
我正在读取 JSON 文件,取出值并进行一些更改。 基本上我向数组添加了一些值。之后我想将其写回到文件中。当我将 JSONArray 写回文件时,会被写入字符串而不是 JSONArray 对象。怎样才
我为两个应用程序使用嵌入式数据库,其中一个是服务器,另一个是客户端。客户端应用程序。可以向服务器端发送获取数据请求以检索数据并显示在表格(或其他)中。问题是这样的:如何将获取的数据保存(写入)到页面文
是否有更好的解决方案来快速初始化 C 数组(在堆上创建)?就像我们使用大括号一样 double** matrix_multiply(const double **l_matrix, const dou
从问题得出问题:找到所有 result = new ArrayList(); for (int i = 2; i >(i%8) & 0x1) == 0) { result.add(i
由于某种原因,它没有写入 CSV。谁能明白为什么它不写吗? def main(): list_of_emails = read_email_csv() #read input file, cr
关闭。 这个问题是 not reproducible or was caused by typos 。它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能在这里出现,
我目前正在开发一个保存和加载程序,但我无法获得正确的结果。 编写程序: #include #include #define FILENAME "Save" #define COUNT 6 type
import java.io.*; public class Main2 { public static void main(String[] args) throws Exception {
我需要使用预定义位置字符串“Office”从所有日历中检索所有 iOS 事件,然后将结果写入 NSLog 和 UITextView。 到目前为止,这是我的代码: #import "ViewCo
我正在尝试将 BOOL 值写入 PFInstallation 中的列,但会不停地崩溃: - (IBAction)pushSwitch:(id)sender { NSUserDefaults *push
我以前在学校学过一些简单的数据库编程,但现在我正在尝试学习最佳实践,因为我正在编写更复杂的应用程序。写入 MySQL 数据库并不难,但我想知道让分布式应用程序写入 Amazon EC2 上的远程数据库
是否可以写回到ResourceBundle?目前我正在使用 ResourceBundle 来存储信息,在运行时使用以下内容读取信息 while(ResourceBundle.getBundle("bu
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我是一名优秀的程序员,十分优秀!