users@glassfish.java.net

Re: Question about changing PUs used by EJB with embedded Glassfish for unit testing

From: NBW <emailnbw_at_gmail.com>
Date: Mon, 21 Mar 2011 15:51:46 -0400

On Mon, Mar 21, 2011 at 3:28 PM, Mitesh Meswani
<mitesh.meswani_at_oracle.com>wrote:

> On 3/21/2011 12:19 PM, NBW wrote:
>
> Hi Mitesh -
>
> I see this as problematic for a couple of reasons.
>
> First using the persistence.xml I am able to set properties per PU, for
> example when running against my embedded test PU I would like to set
> "eclipselink.target-database" to "Derby". I also need to set
> "eclipselink.ddl-generation" to "drop-and-create-tables".
>
> Assuming above two are the only properties you need to override, it is
> possible to still reuse the PU. eclipselink.target-database normally is not
> needed to be set as EclipseLink is good at "auto detecting" database it is
> running against. You can override eclipselink.ddl-generation using arguments
> to "asadmin deploy" (check the man page).
>

That's interesting though it would constrain deployment to using asadmin vs.
the web admin UI since the --createtables and --dropandcreatetables
functionality doesn't appear exposed in the UI.


> However, I need these properties set to different values when running in
> the non-embedded context. I would not be able to do this with only one PU.
>
> If there are are more than these properties, then I think the ant route you
> referred to seems to be the least intrusive route.
>
> -Mitesh
>

OK well I guess that is what I will end up doing at some point. Its too bad
there isn't something as simple as

<persistence>
  <persistence-unit name="foo" ... />
  <persistence-unit name="bar" ... />
  <default-unit>bar</default-unit>
</persistence>

Then anytime a @PersistenceContext is injected without specifying a unitname
the value of default-unit would be used. That would nicely solve this and
make switching into a test context much simpler then it currently is.

-Noah


>
> Secondly, your suggestion implies an embedded.glassfish.installation.root
> which is different from my full GFv3.1 install which is what I have it set
> to now. I have been unable to get embedded glassfish to start when I point
> the installation.root to a staging directory. This is the case even after
> copying all the files it complained about not being able to find in the
> staging directory. Currently it is complaining about not being able to
> connect to 1527 even though I am using org.apache.derby.jdbc.EmbeddedDriver.
> It works fine when I point things to the full gf-install. I suspect I am
> missing a jar or some such but that's besides the point. I could always make
> a copy of the full install to use for testing as ugly as that would be.
>
> I see my first point as being the deal breaker.
>
> -Noah
>
> On Mon, Mar 21, 2011 at 3:02 PM, Mitesh Meswani <mitesh.meswani_at_oracle.com
> > wrote:
>
>> I would suggest you to map the data source as needed in your environment
>> instead of maintaining two different PUs. Lets say you are referring to
>> "jdbc/mydb" from pu "FOO" in persistence.xml. Configure your embedded GF
>> instance to point
>> "jdbc/mydb" to embedded derby and configure your normal GlassFish to point
>> it to the non embedded db.
>>
>>
>> On 3/21/2011 11:51 AM, NBW wrote:
>>
>>> I'm using embedded glassfish to test out some EJBs which include JPA code
>>> and inject their entity manager's like so:
>>>
>>> @Stateless
>>> public class MyBean {
>>>
>>> @PersistenceContext(unitname = "FOO")
>>> private EntityManager em;
>>>
>>> ...
>>> }
>>>
>>>
>>> My persistence.xml defines PU FOO and it defines PU FOO-TEST. FOO-TEST
>>> uses derby embedded and I want to select that PU when the EJB is run in a
>>> test. My tests are running in embedded GF like so:
>>>
>>> Map<String, Object> props = new HashMap<String, Object>();
>>> props.put(EJBContainer.APP_NAME, myApp);
>>> props.put(EJBContainer.MODULES, new File("out/production/MYAPP"));
>>> props.put("org.glassfish.ejb.embedded.glassfish.installation.root",
>>> "C:/glassfish");
>>>
>>> EJBContainer ejbC = EJBContainer.createEJBContainer(props);
>>> Context ctx = ejbC.getContext();
>>> MyBean myBean = (MyBean) ctx.lookup("java:global/myApp/MYAPP/MyBean");
>>> Assert.assertNotNull(myBean);
>>> ejbC.close();
>>>
>>> So the unit name in the bean is set. Is there a way to override this for
>>> my tests so that they can use the FOO-TEST pu? I thought about using ANT to
>>> alter the persistence.xml file to set the unit name's prior to packaging
>>> based on the context (production or test) but I don't like that solution.
>>> I'm hoping there's a cleaner way of doing it.
>>>
>>> Thanks,
>>>
>>> -Noah
>>>
>>
>>
>
>