[EJB 3.0] - Is there an EntityListener equivalent for when assocaitions
by benc
I have a scenario where I need to know when an association between two entities is changed in the same fashion as @PostUpdate and @PostPersist in EntityListener. My original assumption was that EntityListener would do what I wanted; but, it seems to only be called for fields that are stored directly in the backing table of an entity... So when I change collections defined by @OneToMany or @ManyToMany with @JoinTable the EntityListener is not called.
I can force the EntityListener to be called by setting another field in the Entity (labeled dirty in the attached code example) but I can't help but think there is a better solution than this.
I've created as simple an ear as I could to demonstrate this behavior. EntityA contains a list of EntityB objects. A servlet has two methods it can call. The first creates an instance of EntityA with 3 instances of EntityB, persists them, then adds another instance of EntityB and persists them. The second method called by the servlet does the same thing except it also sets the dirty field on EntityA when it adds the fourth EntityB instance.
Output from non-dirty servlet run
| 15:39:30,077 INFO [STDOUT] Entity Listener Called for EntityA : 1
| 15:39:30,077 INFO [STDOUT] Dirty : false
| 15:39:30,077 INFO [STDOUT] EntityB list : [1, 2, 3]
|
Output from dirty servlet run
| 15:39:47,241 INFO [STDOUT] Entity Listener Called for EntityA : 2
| 15:39:47,241 INFO [STDOUT] Dirty : false
| 15:39:47,241 INFO [STDOUT] EntityB list : [5, 6, 7]
| 15:39:47,255 INFO [STDOUT] Entity Listener Called for EntityA : 2
| 15:39:47,255 INFO [STDOUT] Dirty : true
| 15:39:47,256 INFO [STDOUT] EntityB list : [5, 6, 7, 8]
|
Source Code:
EntityA.java
| package test;
|
| import java.util.Collection;
|
| import javax.persistence.Entity;
| import javax.persistence.EntityListeners;
| import javax.persistence.GeneratedValue;
| import javax.persistence.Id;
| import javax.persistence.JoinColumn;
| import javax.persistence.JoinTable;
| import javax.persistence.OneToMany;
|
| @Entity
| @EntityListeners(AssociationTestEntityListener.class)
| public class EntityA
| {
| protected int id;
| protected boolean dirty;
| protected Collection<EntityB> b;
|
| @Id
| @GeneratedValue
| public int getId()
| {
| return id;
| }
| public void setId(int id)
| {
| this.id = id;
| }
|
| public boolean isDirty()
| {
| return dirty;
| }
| public void setDirty(boolean dirty)
| {
| this.dirty = dirty;
| }
|
|
| @OneToMany
| @JoinTable(
| name = "a_b",
| joinColumns = {@JoinColumn(name = "b_id")},
| inverseJoinColumns = @JoinColumn(name = "a_id")
| )
| public Collection<EntityB> getB()
| {
| return b;
| }
| public void setB(Collection<EntityB> b)
| {
| this.b = b;
| }
| }
|
EntityB.java
| package test;
|
| import javax.persistence.Entity;
| import javax.persistence.GeneratedValue;
| import javax.persistence.Id;
|
| @Entity
| public class EntityB
| {
| protected int id;
|
| @Id
| @GeneratedValue
| public int getId()
| {
| return id;
| }
| public void setId(int id)
| {
| this.id = id;
| }
| }
|
AssociationTestEntityListener.java
| package test;
|
| import javax.persistence.PostPersist;
| import javax.persistence.PostUpdate;
|
| public class AssociationTestEntityListener
| {
| @PostPersist
| @PostUpdate
| public void postEvent(EntityA a)
| {
| StringBuffer bstr = new StringBuffer("EntityB list : [");
| for( EntityB b: a.getB())
| {
| bstr.append(b.getId());
| bstr.append(", ");
| }
| bstr.replace(bstr.lastIndexOf(", "), bstr.length(), "]");
|
| System.out.println();
| System.out.println("Entity Listener Called for EntityA : " + a.getId());
| System.out.println("Dirty : " + a.isDirty());
| System.out.println(bstr.toString());
| System.out.println();
| a.setDirty(false);
| }
| }
|
TestListenerStatelessSession.java
| package test;
|
| import java.util.ArrayList;
| import java.util.Collection;
|
| import javax.ejb.Stateless;
| import javax.persistence.EntityManager;
| import javax.persistence.PersistenceContext;
|
| import org.jboss.annotation.ejb.LocalBinding;
|
| @Stateless (name="TestListener")
| @LocalBinding(jndiBinding="AT/TestListener")
| public class TestListenerStatelessSesssion implements TestListenerSession
| {
| @PersistenceContext(unitName="defaultPU")
| EntityManager em;
|
| /* (non-Javadoc)
| * @see test.TestListenerSession#doStuff()
| */
| public void testWithDirty()
| {
| Collection<EntityB> bList = new ArrayList<EntityB>(3);
| bList.add(getNewB());
| bList.add(getNewB());
| bList.add(getNewB());
|
| EntityA a = new EntityA();
| a.setB(bList);
| em.persist(a);
|
| a.setDirty(true);
| bList = a.getB();
| bList.add(getNewB());
| a.setB(bList);
| em.merge(a);
| }
|
| /* (non-Javadoc)
| * @see test.TestListenerSession#doStuff()
| */
| public void testWithoutDirty()
| {
| Collection<EntityB> bList = new ArrayList<EntityB>(3);
| bList.add(getNewB());
| bList.add(getNewB());
| bList.add(getNewB());
|
| EntityA a = new EntityA();
| a.setB(bList);
| em.persist(a);
|
| bList = a.getB();
| bList.add(getNewB());
| a.setB(bList);
| em.merge(a);
| }
|
| private EntityB getNewB()
| {
| EntityB rc = new EntityB();
| em.persist(rc);
| return rc;
| }
| }
|
TestListenerSession.java
| package test;
|
| import javax.ejb.Local;
|
|
| @Local
| public interface TestListenerSession
| {
|
| public abstract void testWithDirty();
| public abstract void testWithoutDirty();
|
| }
|
AT.jsp
| <%@ page import="test.*, javax.naming.*, java.text.*"%>
|
| <%!
| private TestListenerSession tls = null;
| public void jspInit ()
| {
| try
| {
| InitialContext ctx = new InitialContext();
| tls = (TestListenerSession) ctx.lookup("AT/TestListener");
| }
| catch (Exception e)
| {
| e.printStackTrace ();
| }
| }
| %>
|
| <%
| try
| {
| if (request.getParameter("TestWithoutDirty") != null)
| {
| tls.testWithoutDirty();
| }
| else if (request.getParameter("TestWithDirty") != null)
| {
| tls.testWithDirty();
| }
| }
| catch (Exception e)
| {
| e.printStackTrace ();
| }
| %>
|
| <html>
| <body>
|
| <p>Test Listener<br />
| <form action="AT.jsp" method="POST">
| <input type="submit" value="TestWithoutDirty" name="TestWithoutDirty">
| <input type="submit" value="TestWithDirty" name="TestWithDirty">
| </form>
| </p>
|
| </body>
| </html>
|
Application.xml
| <?xml version="1.0" encoding="UTF-8"?>
| <application
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
| xmlns="http://java.sun.com/xml/ns/javaee"
| xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd"
| xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
| http://java.sun.com/xml/ns/javaee/application_5.xsd"
| id="Application_ID"
| version="5">
| <module>
| <web>
| <web-uri>ROOT.war</web-uri>
| <context-root>/</context-root>
| </web>
| </module>
| <module>
| <ejb>AssociationTest.jar</ejb>
| </module>
| </application>
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4143307#4143307
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4143307
18 years, 1 month
[JBoss Tools (users)] - Re: Deploying Seam (Servers and Runtimes)
by redbird
I could not locate the J2EE version of 3.3.1.1 Eclipse. I did find the standard 3.3.1.1 download. I tried that, but the Seam tools do not show up. I assume it is because it is not the J2EE version? I don't know.
Do you happen to have a link to the J2EE download for version 3.3.1.1 of Eclipse? I couldn't find it. Or do you know what plugins I may have to install to the standard release to "recreate" the J2EE version?
I'm obviously getting very frustrated. All I wanted to do was create a Seam project (with no extra code yet) and deploy it to Jboss. That's it. I've been fighting with the tools for over 2 days to try and do this. It seems like I must be doing something wrong, because I can't believe it is this hard. I figured it would just be something like "Create Seam Project". Then "Deploy". Then I could start adding my code to it. But I just can't seem to figure out what it is that I'm doing wrong.
Please post a link to the J2EE eclipse 3.3.1.1 if you have it or a list of plugins I need to get 3.3.1.1 workable with JBoss tools. Or if you can see what I'm doing wrong. That would be very helpful. Sorry for the rant. I'm just very tired and very frustrated right now. Thanks.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4143305#4143305
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4143305
18 years, 1 month
[JBossWS] - Web services using common complex types
by rcarmichael
Although I am an experienced programmer, I have to admit I am relatively new to Web Services and XML in general, so please bear with me...
Let's say I have two web services, WS_A and WS_B. They both reference POJO_C (let's say both WS_A and WS_B have a function called getC that returns POJO_C). I annotate WS_A and WS_B with @WebService and deploy them and JBoss provides the web services as intended.
However, when I generate client stubs (using wsimport), I put WS_A and WS_B in different packages. Both of those client packages end up having an object 'C' with different package names, so that WS_A.C != WS_B.C, even though I might want to use them interchangeably.
Is the solution to this problem providing custom bindings to wsimport that moves 'C' into the same package when I run wsimport on both web services? I would think that maybe there is some way to tell JBoss that C is a shared object and put it into a XSD or something that both web services could share.
I know this is a simple thing, thanks for the help.
- Ryan
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4143302#4143302
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4143302
18 years, 1 month
[Installation, Configuration & DEPLOYMENT] - Expected release of JBossAS-5.0.0.GA?
by sumitsu
I was curious as to whether there is an approximate expected release date of the stable revision of the 5.0 JBoss AS.
The reason I ask is that my team is planning to upgrade our existing JBoss 4.0.2 installations in the near future. We would prefer to make the jump to 5.0, but there will be some significant investment in re-testing our applications and in self-training in advance of an upgrade (regardless of which version we go to), so it would not be worth doing that preparation for JBoss 5 if deadlines end up forcing us to go with 4.2.2 anyway.
In early November 2007, Dimitris Andreadis forecast 5.0 GA to be released in February of this year (assuming that the poster there is, in fact, Dimitris Andreadis) -- is there a revised expectation now? I understand from the JBoss AS JIRA that issues are still currently being worked out in the Candidate Release.
Thanks in advance for any information. Apologies if this is not the correct forum for this inquiry.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4143294#4143294
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4143294
18 years, 1 month
[Javassist user questions] - Final fields, paramters and local variables
by Coloss
Hello,
I am using Javassist only since a few weeks and I have tried out to create my own classes at runtime with final fields, function parameters and variables.
The surprising thing was that i wasn't able at all to have this working (for parameters I have found out that Javassist doesn't seem to allow me to specify this kind of propriety. Am I right?).
For local variables and fields the code compiles (thing that is not done with parameters) but the final propriety is not really applied (I am still able to change this variable many times).
Is this a bug or am I doing something wrong?
Compilation fails:
| CtMethod m = CtMethod.make("private void printString (final String s)
| { System.out.print(s); }",newClass);
| newClass.addMethod(m);
|
Code that compiles but doesn't apply the final propriety (LV)
| CtMethod m = CtMethod.make("private void printString (String s) {
| final String prefix = \"> \"; prefix = \">>\";
| System.out.print(prefix + s); }",newClass);
| newClass.addMethod(m);
|
Code that compiles but doesn't apply the final propriety (Fields)
| CtField field = new CtField(CtClass.intType, "x",newClass);
| field.setModifiers(Modifier.FINAL);
| newClass.addField(field);
|
| CtMethod m = CtMethod.make("private void setX (int x)
| { this.x = x; this.x++; }",newClass);
| newClass.addMethod(m);
|
Thanks in advance for the answer.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4143286#4143286
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4143286
18 years, 1 month