这段代码:
@Override public List<FactCodeDto> getAllFactsWithoutParentsAsFactDto() { String completeQuery = FactCodeQueries.SELECT_DTO_FROM_FACT_WITH_NO_PARENTS; Query query = createHibernateQueryForUnmappedTypeFactDto(completeQuery); List<FactCodeDto> factDtoList = query.list(); //line 133 return factDtoList; }
调用此方法:
private Query createHibernateQueryForUnmappedTypeFactDto(String sqlQuery) throws HibernateException { return FactCodeQueries.addScalars(createSQLQuery(sqlQuery)).setResultTransformer(Transformers.aliasToBean(FactCodeDto.class)); }
给我一个ClassCastException->跟踪的一部分:
Caused by: java.lang.ClassCastException: org.bamboomy.cjr.dto.FactCodeDto cannot be cast to java.util.Map at org.hibernate.property.access.internal.PropertyAccessMapImpl$SetterImpl.set(PropertyAccessMapImpl.java:102) at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:78) at org.hibernate.hql.internal.HolderInstantiator.instantiate(HolderInstantiator.java:75) at org.hibernate.loader.custom.CustomLoader.getResultList(CustomLoader.java:435) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2423) at org.hibernate.loader.Loader.list(Loader.java:2418) at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:336) at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1898) at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:318) at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:125) at org.bamboomy.cjr.dao.factcode.FactCodeDAOImpl.getAllFactsWithoutParentsAsFactDto(FactCodeDAOImpl.java:133)
这很奇怪,因为,实际上,如果您查找Hibernate的源代码,它将尝试执行以下操作:
@Override @SuppressWarnings("unchecked") public void set(Object target, Object value, SessionFactoryImplementor factory) { ( (Map) target ).put( propertyName, value ); //line 102 }
这没有任何意义…
目标的类型为Class,此代码尝试将其强制转换为Map,
为什么要尝试这样做???
任何指针都值得欢迎…
我正在使用Hibernate 5(并且正在从3升级)…
编辑:我也使用Spring(4.2.1.RELEASE;也进行升级),它在部署时调用这些方法,任何调试指针也都非常受欢迎…
编辑2 :(根据要求,整个FactCodeDto类)
package org.bamboomy.cjr.dto; import org.bamboomy.cjr.model.FactCode; import org.bamboomy.cjr.model.FactCodeType; import org.bamboomy.cjr.utility.FullDateUtil; import org.bamboomy.cjr.utility.Locales; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.springframework.util.Assert; import java.util.*; @Getter @Setter @ToString public class FactCodeDto extends TreeNodeValue { private String cdFact; private String cdFactSuffix; private Boolean isSupplementCode; private Boolean isTitleCode; private Boolean mustBeFollowed; private Date activeFrom; private Date activeTo; private Boolean isCode; private Long idFact; private Long idParent; private String type; Map<Locale, String> description = new HashMap<Locale, String>(3); public FactCodeDto() { } public FactCodeDto(String prefix, String suffix) { super(); this.cdFact = prefix; this.cdFactSuffix = suffix; } public FactCodeDto(String cdFact, String cdFactSuffix, Boolean isSupplementCode, Boolean mustBeFollowed) { super(); this.cdFact = cdFact; this.cdFactSuffix = cdFactSuffix; this.isSupplementCode = isSupplementCode; this.mustBeFollowed = mustBeFollowed; } public FactCodeDto(String cdFact, String cdFactSuffix, Boolean isSupplementCode, Boolean mustBeFollowed, Long idFact, Long idParent, Boolean isCode, Boolean isTitleCode, Date from, Date to, Map<Locale, String> descriptions,String type) { super(); this.cdFact = cdFact; this.cdFactSuffix = cdFactSuffix; this.isSupplementCode = isSupplementCode; this.mustBeFollowed = mustBeFollowed; this.idFact = idFact; this.idParent = idParent; this.isCode = isCode; this.isTitleCode = isTitleCode; this.activeFrom = from; this.activeTo = to; if (descriptions != null) { this.description = descriptions; } this.type = type; } public FactCodeDto(FactCode fc) { this(fc.getPrefix(), fc.getSuffix(), fc.isSupplementCode(), fc.isHasMandatorySupplCodes(), fc.getId(), fc.getParent(), fc.isActualCode(), fc.isTitleCode(), fc.getActiveFrom(), fc.getActiveTo(), fc.getAllDesc(),fc.getType().getCode()); } public String formatCode() { return FactCode.formatCode(cdFact, cdFactSuffix); } public boolean isActive() { Date now = new Date(System.currentTimeMillis()); return FullDateUtil.isBetweenDates(now, this.activeFrom, this.activeTo); } public void setDescFr(String s) { description.put(Locales.FRENCH, s); } public void setDescNl(String s) { description.put(Locales.DUTCH, s); } public void setDescDe(String s) { description.put(Locales.GERMAN, s); } /** * public String toString() { * StringBuilder sb = new StringBuilder(); * sb.append(getIdFact() + ": ") * .append(getIdParent() + ": ") * .append(" " + cdFact + cdFactSuffix + ": " + (isSupplementCode ? "NO Principal " : " Principal ")) * .append((mustBeFollowed ? " Must Be Followed " : "NOT Must Be Followed ")); * return sb.toString(); * } */ public Map<Locale, String> getDescription() { return description; } @Override public int hashCode() { final int prime = 31; int result = 1; String fullCode = formatCode(); result = prime * result + ((fullCode == null) ? 0 : fullCode.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } FactCodeDto other = (FactCodeDto) obj; return formatCode().equals(other.formatCode()); } @Override public boolean isChildOf(TreeNodeValue value) { Assert.notNull(value); boolean isChild = false; if (value instanceof FactCodeDto) { if (this.getIdParent() != null) { isChild = this.getIdParent().equals(((FactCodeDto) value).getIdFact()); } } return isChild; } @Override public boolean isBrotherOf(TreeNodeValue value) { Assert.notNull(value); boolean isBrother = false; if (value instanceof FactCodeDto) { if (this.getIdParent() != null) { isBrother = this.getIdParent().equals(((FactCodeDto) value).getIdParent()); } } return isBrother; } @Override public boolean isParentOf(TreeNodeValue value) { Assert.notNull(value); boolean isParent = false; if (value instanceof FactCodeDto) { isParent = this.getIdFact().equals(((FactCodeDto) value).getIdParent()); } return isParent; } @Override public int compareTo(TreeNodeValue to) { if (to instanceof FactCodeDto) { return formatCode().compareTo(((FactCodeDto) to).formatCode()); } else return 1; } public String getCode() { return formatCode(); } }
最后,找到解决方案并不难,
我刚刚创建了自己的(自定义)ResultTransformer,并在setResultTransformer方法中进行了指定:
private Query createHibernateQueryForUnmappedTypeFactDto(String sqlQuery) throws HibernateException { return FactCodeQueries.addScalars(createSQLQuery(sqlQuery)).setResultTransformer(new FactCodeDtoResultTransformer()); //return FactCodeQueries.addScalars(createSQLQuery(sqlQuery)).setResultTransformer(Transformers.aliasToBean(FactCodeDto.class)); }
自定义结果转换器的代码:
package org.bamboomy.cjr.dao.factcode; import org.bamboomy.cjr.dto.FactCodeDto; import java.util.Date; import java.util.List; /** * Created by a162299 on 3-11-2015. */ public class FactCodeDtoResultTransformer implements org.hibernate.transform.ResultTransformer { @Override public Object transformTuple(Object[] objects, String[] strings) { FactCodeDto result = new FactCodeDto(); for (int i = 0; i < objects.length; i++) { setField(result, strings[i], objects[i]); } return result; } private void setField(FactCodeDto result, String string, Object object) { if (string.equalsIgnoreCase("cdFact")) { result.setCdFact((String) object); } else if (string.equalsIgnoreCase("cdFactSuffix")) { result.setCdFactSuffix((String) object); } else if (string.equalsIgnoreCase("isSupplementCode")) { result.setIsSupplementCode((Boolean) object); } else if (string.equalsIgnoreCase("isTitleCode")) { result.setIsTitleCode((Boolean) object); } else if (string.equalsIgnoreCase("mustBeFollowed")) { result.setMustBeFollowed((Boolean) object); } else if (string.equalsIgnoreCase("activeFrom")) { result.setActiveFrom((Date) object); } else if (string.equalsIgnoreCase("activeTo")) { result.setActiveTo((Date) object); } else if (string.equalsIgnoreCase("descFr")) { result.setDescFr((String) object); } else if (string.equalsIgnoreCase("descNl")) { result.setDescNl((String) object); } else if (string.equalsIgnoreCase("descDe")) { result.setDescDe((String) object); } else if (string.equalsIgnoreCase("type")) { result.setType((String) object); } else if (string.equalsIgnoreCase("idFact")) { result.setIdFact((Long) object); } else if (string.equalsIgnoreCase("idParent")) { result.setIdParent((Long) object); } else if (string.equalsIgnoreCase("isCode")) { result.setIsCode((Boolean) object); } else { throw new RuntimeException("unknown field"); } } @Override public List transformList(List list) { return list; } }
在hibernate3中,您可以将Aliasses设置为查询,但是在hibernate5中不能再执行此操作(如果我错了,请纠正我),因此aliasToBean是您只能在实际使用别名时使用的东西;我没有,所以例外。