I spent a couple of days wrestling an issue so I thought I'd post the solution.
I'm using the new acls on hibernate persisted objects. I am using a lot of code from the Contacts example including the JdbcMutableAclService.
My app was able to create new ACL's for my hibernate persisted objects, but I was not able to retrieve the ACL for an object after I retrieved it from my hibernate DAO.
The problem is Hibernate proxies the objects so a call to <object>.getClass() returns the CGLib proxied object... which means .getClass().getName() returns a string that is <className>$$$EnhancerByCGILIB$$$etc.etc
Hibernate provides a static method that knows how to turn a proxied object into a real object... so, Hibernate.getClass(proxiedObject).getName() will return the correct class name.
To fix this I had to create a new ObjectIdentityImpl mine is called HibernateObjectIdentityImpl
I hacked up jdbcMutableAclService by replacing every occurrence of ObjectIdentityImpl with HibernateObjectIdentityImpl.Code:public class HibernateObjectIdentityImpl extends ObjectIdentityImpl{ private Class javaType; public HibernateObjectIdentityImpl(String javaType, Serializable identifier) { super(javaType, identifier); } public HibernateObjectIdentityImpl(Class javaType, Serializable identifier) { super(javaType,identifier); } public HibernateObjectIdentityImpl(Object object) throws IdentityUnavailableException { super(object); this.javaType = Hibernate.getClass(object); } public Class getJavaType() { return javaType; } /** * Important so caching operates properly. * * @return the hash */ public int hashCode() { int code = 31; code ^= this.javaType.hashCode(); code ^= super.getIdentifier().hashCode(); return code; } public String toString() { StringBuffer sb = new StringBuffer(); sb.append(this.getClass().getName()).append("["); sb.append("Java Type: ").append(this.javaType); sb.append("; Identifier: ").append(super.getIdentifier()).append("]"); return sb.toString(); } }
Now you also have to tell your Voters and your afterInvocationProviders to use the HibernateObjectIdentityImpl... to do this you have to hack together an ObjectIdentityRetrievalStrategy:
put this in your app context:Code:public class HibernateObjectIdentityRetrievalStrategy extends ObjectIdentityRetrievalStrategyImpl{ /** * */ public HibernateObjectIdentityRetrievalStrategy() { super(); // TODO Auto-generated constructor stub } public ObjectIdentity getObjectIdentity(Object domainObject) { return new HibernateObjectIdentityImpl(domainObject); } }
and then add the following property to every one of your voters and your after invocation providers:Code:<bean id="hibernateObjectIdentityRetrievalStrategy" class="net.fiftytwo.HibernateObjectIdentityRetrievalStrategy"/>
That did it for me...Code:<property name="objectIdentityRetrievalStrategy"> <ref local="hibernateObjectIdentityRetrievalStrategy"/> </property>


