我正在MongoDbWriter中使用Spring批处理。
所以我们使用Spring-Data-MongoDB,当ItemWriter被称为Class Cast-Exception时抛出:
10:40:13.795 [jobLauncherTaskExecutor-1] DEBUG o.s.b.c.r.dao.JdbcJobExecutionDao - Truncating long message before update of JobExecution: JobExecution: id=0, version=1, startTime=Wed Jun 17 10:40:01 CEST 2015, endTime=Wed Jun 17 10:40:13 CEST 2015, lastUpdated=Wed Jun 17 10:40:13 CEST 2015, status=FAILED, exitStatus=exitCode=FAILED;exitDescription=java.lang.ClassCastException: com.mongodb.BasicDBObject cannot be cast to com.mongodb.BasicDBList
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:384)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:353)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:78)
at org.springframework.data.mongodb.core.MongoTemplate.toDbObject(MongoTemplate.java:809)
at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:962)
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:911)
at org.springframework.batch.item.data.MongoItemWriter.doWrite(MongoItemWriter.java:128)
at org.springframework.batch.item.data.MongoItemWriter$1.beforeCommit(MongoItemWriter.java:156)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:928)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:740)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:150)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:386)
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:304)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
, job=[JobInstance: id=0, version=0, Job=[NBO.READER.]], jobParameters=[{}]
我们使用spring-data-mongodb-1.7.0。发布,但我认为有一个bug:
MongoTemplate中的“doSave”方法调用toDbObject,此方法返回基本的BobObject,但它是字符串。所以当我保存一个列表时,这个方法返回一个BasicDBObject。。。
private <T> DBObject toDbObject(T objectToSave, MongoWriter<T> writer) {
if (!(objectToSave instanceof String)) {
DBObject dbDoc = new BasicDBObject();
writer.write(objectToSave, dbDoc);
return dbDoc;
} else {
try {
return (DBObject) JSON.parse((String) objectToSave);
} catch (JSONParseException e) {
throw new MappingException("Could not parse given String to save into a JSON document!", e);
}
}
}
在此之后,将调用MappingMongoConverter的write()-方法并引发异常,因为:
if (!handledByCustomConverter && !(dbo instanceof BasicDBList)) {
typeMapper.writeType(type, dbo);
}
但它不是BasicDBList,因为有toDbObject-Method。然后调用写入内部方法,然后:
if (Collection.class.isAssignableFrom(entityType)) {
writeCollectionInternal((Collection<?>) obj, ClassTypeInformation.LIST, (BasicDBList) dbo);
return;
}
这使得boom^^
toDbObject方法似乎是错误的?那是虫子吗?
您好
解决方法是重写MongoTemplate类:
public class MongoHack extends MongoTemplate
{
public MongoHack(MongoDbFactory mongoDbFactory)
{
super(mongoDbFactory);
// TODO Auto-generated constructor stub
}
@Override
protected <T> void doSave(String collectionName, T objectToSave, MongoWriter<T> writer)
{
this.assertUpdateableIdIfNotSet(objectToSave);
maybeEmitEvent(new BeforeConvertEvent<T>(objectToSave));
DBObject dbDoc = this.toDbObject(objectToSave, writer);
maybeEmitEvent(new BeforeSaveEvent<T>(objectToSave, dbDoc));
Object id = saveDBObject(collectionName, dbDoc, objectToSave.getClass());
populateIdIfNecessary(objectToSave, id);
maybeEmitEvent(new AfterSaveEvent<T>(objectToSave, dbDoc));
}
private void assertUpdateableIdIfNotSet(Object entity)
{
MongoPersistentEntity<?> persistentEntity = super.getConverter().getMappingContext()
.getPersistentEntity(entity.getClass());
MongoPersistentProperty idProperty = persistentEntity == null ? null : persistentEntity.getIdProperty();
if (idProperty == null || persistentEntity == null) {
return;
}
Object idValue = persistentEntity.getPropertyAccessor(entity).getProperty(idProperty);
if (idValue == null && !MongoSimpleTypes.AUTOGENERATED_ID_TYPES.contains(idProperty.getType())) {
throw new InvalidDataAccessApiUsageException(String.format(
"Cannot autogenerate id of type %s for entity of type %s!", idProperty.getType().getName(), entity
.getClass().getName()));
}
}
private <T> DBObject toDbObject(T objectToSave, MongoWriter<T> writer)
{
if (Collection.class.isAssignableFrom(objectToSave.getClass())) {
DBObject dbDoc = new BasicDBObject();
Collection<T> objects = (Collection<T>) objectToSave;
Iterator<T> iterator = objects.iterator();
while(iterator.hasNext()) {
writer.write(iterator.next(), dbDoc);
}
return dbDoc;
}
else if (!(objectToSave instanceof String)) {
DBObject dbDoc = new BasicDBObject();
writer.write(objectToSave, dbDoc);
return dbDoc;
}
else {
try {
return (DBObject) JSON.parse((String) objectToSave);
}
catch (JSONParseException e) {
throw new MappingException("Could not parse given String to save into a JSON document!", e);
}
}
}
}
这对我很有用。。。但我不知道这是否是一个有用的用例?
例外情况: java.lang.ClassCastException:com.interconnect.library.gcm.util.checkplayServices(util.java:96),com.interconnect.library.gcm.regiseter.handleRegister(regiseter.java:53),com.interconnect.library.g
问题内容: 尝试将结果集强制转换为映射类时,我收到了hibernate类的类强制转换异常…我能够查看返回的结果集中的数据…但是它以Object []的形式返回我可以将Object []设置为List …我可以正确地进行hibernate映射吗?我从查询中获取了正确的数据,但映射不正确… 映射 映射类 参加班 主要 问题答案: 对于测试,我建议您在产生类强制转换异常的语句周围放置一个try-catc
调用AffineTransform: 它驻留在自定义形状类(YingYang)中。 当我进行调用时,当我试图从绘图面板或在类本身(如果我将返回类型更改为YingYang)中将它转换回一个YingYang时,我会得到一个类转换异常。 java.lang.ClassCastException:java.awt.Geom.Path2D$Double不能强制转换为Animation.Yingyang 任何
线程“main”java.lang.ClassCastException:java.base/jdk.internal.loader.ClassLoaders$AppClassLoader不能强制转换为java.base/java.net.urlClassLoader(位于org.springframework.boot.devtools.restart.defaultrestartinitial
我模拟了Jsch()类,并在下面的方法中获得了类强制转换异常。 原始方法。 联机获取Mockito异常。 例外情况: java.lang.ClassCastException:com.jcraft.jsch。频道$MockitoMock$1983492043不能转换为com.jcraft.jsch.ChannelSftp 测试用例调用方法。
对API控制器的远程调用(通过RestTemboard)(从一侧返回已知对象的List([]),从远程侧返回未知类型的对象)返回