Castor OQLQuery报错:找不到支持AvisOperationsDTO类的引擎
解决Castor v0.9.5.3 OQLQuery找不到DTO类型的问题
针对你遇到的org.exolab.castor.jdo.QueryException: Could not find an engine supporting class com.rte.infocable.api.dto.AvisOperationsDTO错误,结合无法更换ORM或升级版本的限制,提供以下可行方案:
1. 修正DTO映射文件的配置
Castor 0.9.5.3对非持久化DTO的映射有严格要求,确保你的映射XML满足以下条件:
- 根元素为
<mapping>,内部的<class>标签明确设置persistent="false"(因为DTO不是对应单个数据库表的持久化实体):
<mapping> <class name="com.rte.infocable.api.dto.AvisOperationsDTO" persistent="false"> <!-- 字段映射,对应联合查询的列 --> <field name="operationId" type="java.lang.Long"> <sql name="operation_id" type="BIGINT"/> </field> <field name="avisLibelle" type="java.lang.String"> <sql name="avis_libelle" type="VARCHAR"/> </field> <!-- 其他字段映射 --> </class> </mapping>
- 检查全限定类名的拼写(包名、类名大小写),确保和实际类完全一致。
2. 确认映射文件的加载配置
确保database.xml和databaseEchanges.xml中正确引入了DTO的映射文件,且文件路径在类路径下:
- 在
<database>标签内添加<mapping>标签引用:
<database name="your-db-name" engine="mysql"> <!-- 其他配置 --> <mapping href="com/rte/infocable/api/dto/AvisOperationsDTO.xml"/> <!-- 其他映射文件 --> </database>
注意路径格式:如果映射文件放在resources目录下的对应包路径,直接用类路径相对路径即可;若路径错误,Castor会静默忽略映射文件,导致_typeInfo中无该类型。
3. 手动注册DTO类型信息(反射方式)
如果上述配置仍未生效,可通过反射手动将DTO的TypeInfo注入到Castor的_typeInfo哈希表中:
import org.exolab.castor.mapping.Mapping; import org.exolab.castor.mapping.ClassDescriptor; import org.exolab.castor.jdo.TypeInfo; import java.lang.reflect.Field; import java.util.Map; // 初始化时执行一次 public void registerDtoType(Database db) throws Exception { // 加载DTO的映射文件 Mapping mapping = new Mapping(); mapping.loadMapping("com/rte/infocable/api/dto/AvisOperationsDTO.xml"); // 获取Database实例中的_typeInfo字段 Field typeInfoField = db.getClass().getDeclaredField("_typeInfo"); typeInfoField.setAccessible(true); Map<String, TypeInfo> typeInfoMap = (Map<String, TypeInfo>) typeInfoField.get(db); // 生成DTO的TypeInfo并注册 ClassDescriptor desc = mapping.getClassDescriptor(AvisOperationsDTO.class); TypeInfo dtoTypeInfo = new TypeInfo(desc, db.getDatabase()); typeInfoMap.put(AvisOperationsDTO.class.getName(), dtoTypeInfo); }
调用db.getOQLQuery()前先执行该方法,确保类型信息已被加载。
4. 绕开OQL,使用原生SQL手动映射
如果OQL的类型限制难以突破,直接使用原生SQL查询并手动填充DTO是更稳妥的方案:
String unionSql = "SELECT t1.operation_id, t2.avis_libelle FROM table_operations t1 JOIN table_avis t2 ON t1.avis_id = t2.id"; Query sqlQuery = db.createQuery(unionSql); List<AvisOperationsDTO> dtoList = new ArrayList<>(); try { sqlQuery.execute(); ResultSet rs = sqlQuery.getResultSet(); while (rs.next()) { AvisOperationsDTO dto = new AvisOperationsDTO(); dto.setOperationId(rs.getLong("operation_id")); dto.setAvisLibelle(rs.getString("avis_libelle")); // 填充其他字段 dtoList.add(dto); } } finally { sqlQuery.close(); } // 后续返回JsonResponse
这种方式无需依赖Castor的DTO类型注册,直接通过JDBC ResultSet映射,避免OQL的引擎支持问题。
内容的提问来源于stack exchange,提问作者Skunka
相关产品推荐
相关产品推荐

