Hibernate gives weird ClassCast exception (using Transformers)

This code:

@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; } 

call this method:

 private Query createHibernateQueryForUnmappedTypeFactDto(String sqlQuery) throws HibernateException { return FactCodeQueries.addScalars(createSQLQuery(sqlQuery)).setResultTransformer(Transformers.aliasToBean(FactCodeDto.class)); } 

gives me a ClassCastException -> trace part:

 Caused by: java.lang.ClassCastException: be.fgov.just.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 be.fgov.just.cjr.dao.factcode.FactCodeDAOImpl.getAllFactsWithoutParentsAsFactDto(FactCodeDAOImpl.java:133) 

This is rather strange because, indeed, if you look at the source code of Hibernate, it tries to do this:

 @Override @SuppressWarnings("unchecked") public void set(Object target, Object value, SessionFactoryImplementor factory) { ( (Map) target ).put( propertyName, value ); //line 102 } 

Which makes no sense ...

target is of type Class, and this code tries to pass it to Map,

why is he trying to do this?

any pointers are more than welcome ...

I am using Hibernate 5 (and upgrading from 3) ...

edit: I also use Spring (4.2.1.RELEASE, as well as an update), which calls these methods on deployment, any debug pointers are also welcome ...

edit 2: (whole class FactCodeDto, on request)

 package be.fgov.just.cjr.dto; import be.fgov.just.cjr.model.FactCode; import be.fgov.just.cjr.model.FactCodeType; import be.fgov.just.cjr.utility.FullDateUtil; import be.fgov.just.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(); } } 
+7
java spring hibernate
source share
5 answers

After all, it wasn’t so hard to find a solution,

I just created my own custom ResultTransformer and pointed out that in the setResultTransformer method:

 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)); } 

custom transformer result code:

 package be.fgov.just.cjr.dao.factcode; import be.fgov.just.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; } } 

in hibernate 3 you can set Aliasses for requests, but you can no longer do this in hibernate 5 (correct me if I am wrong), therefore aliasToBean is something that you can only use when using aliasses; which I did not, therefore an exception.

+1
source share

I found that AliasToBean has changed in Hibernate 5. For me, adding getter for my field fixes the problem.

+4
source share

I am doing some investigation on this. The problem is that Hibernate converts aliases for column names to uppercase - cdFact becomes cdFact .

Read for a deeper explanation and workaround here: matching Hibernate query results with a custom class?

+3
source share

I got this exception

I named one of the fields in the DTO as " closedIndexValue " after it changed it to " closedindexValue ". The code worked fine. I think this was due to the case of the letter "I".

closedIndexValue β†’ wrong camera closedindexValue β†’ correct camera

Sleep Mode Version: - 5.2.4

0
source share

This exception occurs when both getters are set and the column names are not displayed correctly. Make sure you have the correct getters and setters for the query (the correct names and the correct data types). Read more about this here:

http://javahonk.com/java-lang-classcastexception-com-wfs-otc-datamodels-imagineexpirymodel-cannot-cast-java-util-map/

0
source share

All Articles