-
-
2. Re: @Filter example
anescu May 14, 2007 10:45 AM (in response to anescu)"emsa" wrote:
§8.6
http://docs.jboss.com/seam/1.2.1.GA/reference/en/html/persistence.html#d0e5589
I already read that part. Twice. To me it's like reading chinese. HOW do you make it work??? It doesn't say even in which XML file you have to put that part.
And it doesn't say anything about the other parts of the application (I mean, how do you use the damn filter???). As I said, I have found examples with @Filter in Hibernate, but what else needs to be configured in the Seam Java code to make it work (using annotations, like @Filter, @FilterDef and so on) -
3. Re: @Filter example
fernando_jmt May 14, 2007 11:37 AM (in response to anescu)1.- Define the Filter in your Entity.
@Entity @Table(name="NODE") @org.hibernate.annotations.FilterDef( name = "accessLevelFilter", parameters = {@org.hibernate.annotations.ParamDef(name = "currentAccessLevel", type="integer")} ) @org.hibernate.annotations.Filter( name = "accessLevelFilter", condition = "READ_ACCESS_LEVEL <= :currentAccessLevel" ) public abstract class Node implements Serializable { ... @Column(name = "READ_ACCESS_LEVEL", nullable = false) protected int readAccessLevel; ... }
2.- Configure components.xml<core:filter name="accessLevelFilter"> <core:name>accessLevelFilter</core:name> <core:parameters> <key>currentAccessLevel</key> <value>#{currentAccessLevel}</value> </core:parameters> </core:filter> <core:managed-persistence-context name="restrictedEntityManager" auto-create="true" entity-manager-factory="#{wikiEntityManagerFactory}"> <core:filters><value>#{accessLevelFilter}</value></core:filters> </core:managed-persistence-context>
3.- Set somewhere a value for #{currentAccessLevel}.Contexts.getSessionContext().set("currentAccessLevel", bestRole.getAccessLevel());
4.- Finally use the filtered Persistence Context.@Name("nodeDAO") @AutoCreate @Transactional public class NodeDAO { // Most of the DAO methods use this @In protected EntityManager restrictedEntityManager; ... public Node findNode(Long nodeId) { restrictedEntityManager.joinTransaction(); try { return (Node) restrictedEntityManager .createQuery("select n from Node n where n.id = :nodeId") .setParameter("nodeId", nodeId) .getSingleResult(); } catch (EntityNotFoundException ex) { } catch (NoResultException ex) { } return null; } }
Above steps are based on the Seam wiki example. If you want to see more, check it out.
HTH. -
4. Re: @Filter example
anescu May 14, 2007 11:50 AM (in response to anescu)Thanks for the reply, I hope this will get me started.
Where do I find the Wiki example? It's not included in 1.2.1? I looked for the CVS link but I can't find it anywhere on the site.
Do you have any example on how to define a Class type parameter?
I mean, is this all that is different?... @ParamDef(name="account",type="com.abc.Account") ...
Or there is more? -
5. Re: @Filter example
fernando_jmt May 14, 2007 11:59 AM (in response to anescu)AFAIK, Wiki example is in the CVS only.
Regarding class type parameter, I don't have any example and I don't know much about it. Looks like Hibernate specific stuff, so see Hibernate for this (but I guess you already did it). -
6. Re: @Filter example
anescu May 15, 2007 3:49 AM (in response to anescu)"fernando_jmt" wrote:
AFAIK, Wiki example is in the CVS only.
Can you point me to the Seam CVS URL? I can't find it on JBoss site :(.
Tnx -
7. Re: @Filter example
anescu May 15, 2007 5:51 AM (in response to anescu)"fernando_jmt" wrote:
3.- Set somewhere a value for #{currentAccessLevel}.Contexts.getSessionContext().set("currentAccessLevel", bestRole.getAccessLevel());
4.- Finally use the filtered Persistence Context.@Name("nodeDAO") @AutoCreate @Transactional public class NodeDAO { // Most of the DAO methods use this @In protected EntityManager restrictedEntityManager; ... public Node findNode(Long nodeId) { restrictedEntityManager.joinTransaction(); try { return (Node) restrictedEntityManager .createQuery("select n from Node n where n.id = :nodeId") .setParameter("nodeId", nodeId) .getSingleResult(); } catch (EntityNotFoundException ex) { } catch (NoResultException ex) { } return null; } }
So, i did steps 1 and 2, on no 3 i have an @Out(required = false, scope = ScopeType.SESSION) which should work, but how do I use step 4? I am using a Seam generated project, i can't find anywhere a entityManager, everything is done by Seam. I suppose i have to override a method, but hell if i know which one :(.
Also, now, i tried to deploy with the code i have, i just defined my entityMAnager with this:<core:filter name="hubFilteredChannels"> <core:name>hubFilteredChannels</core:name> <core:parameters> <key>currentHub</key> <value>#{currentHub}</value> </core:parameters> </core:filter> <core:managed-persistence-context name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/entityManagerFactory"> <core:filters><value>#{hubFilteredChannels}</value></core:filters> </core:managed-persistence-context>
And now i get an error when loading the first page:Caused by: org.hibernate.HibernateException: Filter [hubFilteredChannels] parameter [currentHub] value not set
So what is wrong? Why does Seam loads everything on startup??? If I have a bad page I cannot see a thing, the page redirects me to the debug page... -
8. Re: @Filter example
fernando_jmt May 15, 2007 10:51 AM (in response to anescu)Post the page where you are setting the currentHub in the session (where you are using @Out). And also post the code where you are trying to use the entityManager you have configured in components.xml.
-
9. Re: @Filter example
anescu May 16, 2007 3:51 AM (in response to anescu)"fernando_jmt" wrote:
Post the page where you are setting the currentHub in the session (where you are using @Out). And also post the code where you are trying to use the entityManager you have configured in components.xml.
Here is how i use the parameter. It's in a bean that renders a combo box, near the menu:@Out(required = false, scope = ScopeType.SESSION) private Hub currentHub = null;
And as i said, i just changed the generated code for the entity manager to the one that uses also the filter. The only place where we use the entityManager by ourselves is this code, in the authenticate method:this.currentUser = (User) this.entityManager.createQuery("from User where username = :username and password = :password").setParameter("username", this.identity.getUsername()).setParameter("password", this.identity.getPassword().getBytes()).getSingleResult();
In the rest, is used under the hood by seam. As i said, i'm new to this so i don't know what i need to override to use a custom entity manager (this way i can use both of them, i guess)
Also, i get the error when opening the first screen (/home.seam if you want), where the menu should be displayed (as i said, the seam-gen web interface). That is why i don't understand why it's trying to load a collection of entities when i have not even authenticated into the application. That is supposed to do the filter, display only the data i'm supposed to see.
Also, it seems i would need to use both entity managers, as the default one seem to be used to load related entities from the DB, i would like to display in the list only the X entities that correspond to a criteria.
So, what methods do i need to override to use a custom entityManager instead of the default one in a Seam generated skeleton??? -
10. Re: @Filter example
anescu May 16, 2007 5:00 AM (in response to anescu)Ok, I have some progress:
1) I defined 2 entity managers in components.xml:<core:managed-persistence-context name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/entityManagerFactory"/> <core:filter name="hubFilteredChannels"> <core:name>hubFilteredChannels</core:name> <core:parameters> <key>currentHub</key> <value>#{currentHub}</value> </core:parameters> </core:filter> <core:managed-persistence-context name="filteredEntityManager" auto-create="true" entity-manager-factory="#{entityManager}"> <core:filters><value>#{hubFilteredChannels}</value></core:filters> </core:managed-persistence-context>
2) Then I override the getPersistenceContextName in my entity List class:@Override protected String getPersistenceContextName() { System.out.println( "### debug step" ); return "filteredEntityManager"; }
3) Now i can deploy and browse the other parts of the application as before using the filter, but i get an exception when opening the entity list screen, something about a ClassCastException:Caused by: java.lang.ClassCastException: org.jboss.seam.persistence.EntityManagerProxy at org.jboss.seam.core.ManagedPersistenceContext.getEntityManagerFactoryFromJndiOrValueBinding(ManagedPersistenceContext.java:169) at org.jboss.seam.core.ManagedPersistenceContext.initEntityManager(ManagedPersistenceContext.java:77) at org.jboss.seam.core.ManagedPersistenceContext.getEntityManager(ManagedPersistenceContext.java:105) at sun.reflect.GeneratedMethodAccessor137.invoke(Unknown Source)
-
11. Re: @Filter example
fernando_jmt May 16, 2007 9:39 AM (in response to anescu)The reason you got that error resides here:
entity-manager-factory="#{entityManager}"
Just change your second persistence context as follows:<core:managed-persistence-context name="filteredEntityManager" auto-create="true" persistence-unit-jndi-name="java:/entityManagerFactory"> <core:filters><value>#{hubFilteredChannels}</value></core:filters> </core:managed-persistence-context>
-
12. Re: @Filter example
anescu May 16, 2007 12:22 PM (in response to anescu)Thanks,
I was sure i also tested with that code and failed, but apparently now it's working.
I was not able to make it work with an entity type parameter, it's saying something about cannot detecting the type for the parameter. So I tested with a Long parameter (the id of the entity and it's working)
Does anyone know any more about that? The Type would be a POJO entity.
Also another problem. As I said, we have a combo box and the user chooses a "current object". If i go directly on the tab that contains my filtered entity, without setting a current object first, i get this kind of error:Caused by: org.hibernate.HibernateException: Filter [hubFilteredChannels] parameter [currentHubId] value not set at org.hibernate.impl.FilterImpl.validate(FilterImpl.java:145) at org.jboss.seam.persistence.HibernatePersistenceProvider.enableFilter(HibernatePersistenceProvider.java:62)
Why not just use the null value instead???