Enum Does Not Work with DetachedCriteria
binario Nov 20, 2005 8:23 AMHi all,
I've asked this before and got no response.
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=72426
Anyway, I'll try again.
I have an Item class
/** * <a href="Item.java.html"><i>View Source</i></a> */ @Entity @Table(name = "t_item") public class Item implements java.io.Serializable { protected final Log log = LogFactory.getLog(getClass()); private Long id; private String name; private ItemState itemState; // ========================================== // GETTERS AND SETTERS // ========================================== @Id(generate = GeneratorType.AUTO) public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public ItemState getItemState() { return itemState; } public void setItemState(ItemState itemState) { this.itemState = itemState; } }
which has an ItemState
public enum ItemState implements Serializable { EMPTY, RUNNING, FINISHED };
and then I have an ItemManager
/** * Interface defining all Item related tasks for the system * <p> * <a href="ItemManager.java.html"><i>View Source</i></a> * </p> */ public interface ItemManager { Long createItem(Item item); Item getItem(Long itemId); void updateItem(Item item); void deleteItem(Long id); public int searchItemsCount(DetachedCriteria query) ; void deleteAllItems(); }
and an implementation of this class
/** * @author Brian McSweeney */ @Stateless public class ItemManagerBean implements ItemManager { @PersistenceContext private EntityManager manager; protected final Log log = LogFactory.getLog(getClass()); public Long createItem(Item item) { manager.persist(item); return item.getId(); } public Item getItem(Long itemId) { Item j = (Item) manager.createQuery( "select j from Item j where j.id=:itemId").setParameter("itemId", itemId).getSingleResult(); return j; } public void updateItem(Item item) { manager.merge(item); } public void deleteItem(Long itemId) { Item item = getItem(itemId); manager.remove(item); } public int searchItemsCount(DetachedCriteria query){ Session session = ((HibernateSession) this.manager).getHibernateSession(); int count = (Integer) query.getExecutableCriteria(session).uniqueResult(); return count; } public void deleteAllItems(){ List<Item> items = manager.createQuery("select i from Item i").getResultList(); for(Item it: items){ deleteItem(it.getId()); } } }
Now I intend to use this from a webapp, so to test it I have a webapplistener class:
/* * @web.listener */ public class WebAppListener implements ServletContextListener { private static Logger log = Logger.getLogger(WebAppListener.class); private ItemManager itemManager = null; private ServletContext sc; /** Constructs a new SimpleListener. */ public WebAppListener() { try { InitialContext ctx = new InitialContext(); itemManager = (ItemManager) ctx.lookup(ItemManager.class.getName()); if(log.isDebugEnabled()){ log.debug("GOT THE MANAGERS OK"); } } catch (Exception e) { log.error("\n\n something buggered up creating the managers", e); } } public void contextDestroyed(ServletContextEvent sce) { if(log.isDebugEnabled()){ log.debug("The web app is stopping"); } } public void contextInitialized(ServletContextEvent sce) { if(log.isDebugEnabled()){ log.debug("The web app is started"); } log.info("About to delete all items"); itemManager.deleteAllItems(); log.info("Deleted all items"); Item item1 = new Item(); item1.setName("item1"); item1.setItemState(ItemState.RUNNING); Item item2 = new Item(); item2.setName("item2"); item2.setItemState(ItemState.RUNNING); log.info("About to create item 1"); itemManager.createItem(item1); log.info("Created item 1"); log.info("About to create item 2"); itemManager.createItem(item2); log.info("Create item 2"); DetachedCriteria criteria = createCriteriaQuery(ItemState.RUNNING); log.info("Created criteria, about to call the query"); int result = searchItemsCount(criteria); log.info("Successfully called the query"); log.info("Row result is: "+result); } private int searchItemsCount(DetachedCriteria query){ return itemManager.searchItemsCount(query); } private DetachedCriteria createCriteriaQuery(ItemState itemState){ DetachedCriteria query = DetachedCriteria.forClass(Item.class); if(itemState!=null){query.add(Expression.eq("itemState",itemState.ordinal()));} query.setProjection(Projections.rowCount()); return query; } }
Now when I kick off this query I get the following exception:
13:08:41,967 INFO [WebAppListener] Created criteria, about to call the query 13:08:48,126 ERROR [[/]] Exception sending context initialized event to listener instance of class com.example.web.listeners.WebAppListener javax.ejb.EJBException: null; CausedByException is: java.lang.Integer at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:46) at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:70) ... ... ... at java.lang.Thread.run(Unknown Source) java.lang.ClassCastException: java.lang.Integer at org.hibernate.type.EnumType.nullSafeSet(EnumType.java:121) at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:155) at org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1514)
please help me!!
thanks,
Brian