Why datasource is not found in JNDI after injection from jndi.properties? - java

This is my persistence.xml:
<persistence>
<persistence-unit name="MyUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/abcDS</jta-data-source>
</persistence-unit>
</persistence>
This is jndi.properties file from src/test/resources which is supposed to create a datasource during testing, since a real application server with a real datasource is absent:
java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory
jdbc/abcDS=new://Resource?type=DataSource
jdbc/abcDS.JdbcDriver=org.hsqldb.jdbcDriver
jdbc/abcDS.JdbcUrl=jdbc:hsqldb:mem:testdb
jdbc/abcDS.JtaManaged=true
jdbc/abcDS.DefaultAutoCommit=false
jdbc/abcDS.UserName=sa
jdbc/abcDS.Password=
This is the test class:
public class FinderTest {
#BeforeClass
public static void startEJB() throws Exception {
InitialContext ic = new InitialContext();
ic.lookup("jdbc/abcDS");
}
}
Unfortunately, the datasource is not created and this is what I keep seeing:
[...]
javax.naming.NameNotFoundException: Name "jdbc/abcDS" not found.
at org.apache.openejb.core.ivm.naming.IvmContext.federate(IvmContext.java:193)
at org.apache.openejb.core.ivm.naming.IvmContext.lookup(IvmContext.java:150)
at org.apache.openejb.core.ivm.naming.IvmContext.lookup(IvmContext.java:124)
at org.apache.openejb.core.ivm.naming.ContextWrapper.lookup(ContextWrapper.java:115)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.XXX.FinderTest.startEJB(FinderTest.java:31)
[...]
What am I doing wrong? Please help!
ps. By the way it works this way (what's going on???):
ic.lookup("java:/openejb/Resource/jdbc/abcDS");

Should be found if you lookup openejb:Resource/jdbc/abcDS
As well you can get injection in your TestCase. Basically, you:
add an empty src/test/resources/META-INF/application-client.xml or ejb-jar.xml
Annotate your test with #LocalClient
Call initialContext.bind("inject", this)
See the testcase-injection example in the examples.zip
EDIT If the lookup still fails, post your log output (the console output).

Related

Spring: Table already exists error! #DirtiesContext and EmbeddedDatabaseBuilder doesn work together?

I got some errors while running a junit test class.
Here's my test class.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=TestApplicationContext.class)
#DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)
public class UserDaoTestDrive {
#Autowired
private UserDao dao;
This is my java class that I used for the configuration.
#Configuration
#EnableTransactionManagement
public class TestApplicationContext {
...
#Bean
public DataSource embeddedDatabase() {
return new EmbeddedDatabaseBuilder().setName("embeddedDatabase").setType(HSQL).addScript("classpath:springbook/user/sqlservice/updatable/sqlRegistrySchema.sql").build();
}
This is the error message.
Error creating bean with name 'embeddedDatabase' defined in class springbook.TestApplicationContext:
Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method [public javax.sql.DataSource springbook.TestApplicationContext.embeddedDatabase()] threw exception;
nested exception is org.springframework.dao.DataAccessResourceFailureException: Failed to execute database script;
...Caused by: java.sql.SQLException: Table already exists
And I've got this weird test result, which fails every other test method.
I have 7 test methods and 1,3,5,7 always succeed and 2,4,6 always fail.
I have no idea why I get these errors because my test class worked well when I used an XML file for the context configuration
My XML file was like this.
<jdbc:embedded-database id="embeddedDatabase" type="HSQL">
<jdbc:script location="classpath:springbook/user/sqlservice/updatable.sqlRegistrySchema.sql" />
<jdbc:embedded-database>
sqlRegistrySchema file
CREATE TABLE SQLMAP(
KEY_ VARCHAR(100) PRIMARY KEY,
SQL_ VARCHAR(100) NOT NULL);
Can anyone tell me why?
I guess the embedded db isn't closed as soon as every test method is finished.
I suggest to try CREATE TABLE IF NOT EXISTS in your sql script. It looks like DB is hanging somewhere in the memory.

EntityManager object is not getting injected with Glassfish and Spring

I have been trying to create a job to delete all records from database. This job is deployed with my webservice. In webservice I can easily access my EntityManager and it's having no issues so far. But, whenever I try to access EntityManager in my scheduler then it gives me NullPointerException. Even I have tried to inject a service that I have created and tried to access it's method. The method which have no database related work is working fine and returning me result. But, the method which is using entityManager inside is throwing me the same exception.
While if I directly call the service using URL each and everything works fine in service as well.
#Service
public class DeletionJob {
#PersistenceContext(unitName = "my_pu")
private EntityManager em;
#Autowired
private REST restClass;
#Scheduled(fixedDelay=10000)
public void run() {
boolean flag = false;
System.out.println(restClass.executeWithoutDB());
System.out.println(restClass.executeWithDB());
}
}
Configuration Class:
#EnableWebMvc
#Configuration
#EnableScheduling
#ComponentScan({ "com.jobs.*" })
#javax.ws.rs.ApplicationPath("webresources")
public class AppConfig extends Application {
#Bean
public DeletionJob myDeletionJob() {
return new DeletionJob();
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver
= new InternalResourceViewResolver();
return viewResolver;
}
#Bean
public REST restClass(){
return new REST();
}
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
addRestResourceClasses(resources);
return resources;
}
/**
* Do not modify addRestResourceClasses() method.
* It is automatically populated with
* all resources defined in the project.
* If required, comment out calling this method in getClasses().
*/
private void addRestResourceClasses(Set<Class<?>> resources) {
resources.add(com.service.REST.class);
// Tried to include deletionjob class here but, no luck still the same.
// resources.add(com.jobs.DeletionJob.class);
}
}
persistance.xml file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="my_pu" transaction-type="JTA">
<jta-data-source>ds</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
</persistence>
I have also tried to use this PersistenceAnnotationBeanPostProcessor component. But after including spring-orm it has even started giving me excpetion of BeanInitializationException. Secondly, I am not fond of using too many libraries. So, would like to do this thing in a simplest possible way. I could do it by looking up JNDI, but, the problem is that I want to use Spring or JAVA EE 6 scheduler API.
Version of GlassFish Server: 4.1
#PersistenceContext is simply getting ignored here.
An entity manager can only be injected in classes running inside a transaction.
Use an EntityManagerFactory to create and destroy an EntityManager.
#PersistenceUnit(unitName = "my_pu")
private EntityManagerFactory entityManagerFactory;
And inside your method use below line to create EntityManager:-
EntityManager entityManager = entityManagerFactory.createEntityManager();
Refer this link:- Injection of Persistence Context in spring
I feel your Persistence Context is not getting initialized properly.

implementing multitenancy in hibernate 4

I am trying to build multitenancy based on unique schema for each client
So there would be a single datasource to Oracle in weblogic server
the datasource would have a user which has synonyms / grants to all client schemas
Let us ignore the fact whether this is good or bad or horrible design - I just want to find a way to get it to work
I am defining the datasource as a part of my hibernate.cfg.xml file
The sessionfactory will get created from this hibernate.cfg.xml
From reading on the internet - I will have to add additional properties in my hibernate.cfg.xml
<session-factory>
<property name="connection.datasource">MYSQLDS</property>
<property name="default_schema">testpage</property>
<!-- multitenant properties start here -->
<property name="multi_tenant_connection_provider">multiTenantConnectionProvider</property>
<property name="multiTenancy">SCHEMA</property>
<property name="tenant_identifier_resolver">CurrentTenantIdentifierResolverImpl</property>
&globalpit;
</session-factory>
Now is the part that I dont understand:
It seems for CurrentTenantIdentifierResolverImpl I will implement a custom class that will implement the interface
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
public class SchemaResolver implements CurrentTenantIdentifierResolver {
#Override
public String resolveCurrentTenantIdentifier() {
return "master";
}
#Override
public boolean validateExistingCurrentSessions() {
return false;
}
}
So I am quite confused how this class and its methods will get invoked - I do understand that this is used to determine which schema is to be used based on some identifier unique to a client - ala user http session ?
The next part is the implementation of MultiTenantConnectionProvider and again its methods such as
public Connection getConnection(String tenantIdentifier) throws SQLException {
RANT -START This strangely starts looking like good old plain and simple JDBC :) so am wondering why I have to use hibernate :(
RANT-END
So related to this method and the class - how do I consume it ?
The frustrating part is lots of places where you get to see these two classes defined - but no explanation of how these are invoked ?
Is there a complete end to end example of how to use these two classes with a clear example of how these two classes are consumed - not just the two stand alone classes please !

What to put into jta-data-source of persistence.xml?

What value should I place into <jta-data-source> of my persistence.xml?
In glassfish admin panel I created a datasource name "abcDS". In my jndi.properties (inside src/test/resources) I defined it like this:
[...]
abcDS=new://Resource?type=DataSource
abcDS.JdbcDriver=org.hsqldb.jdbcDriver
abcDS.JdbcUrl=jdbc:hsqldb:mem:testdb
abcDS.JtaManaged=true
[...]
What shall I place into persistence.xml? I've found a lot of variants in the Net, like: "jdbc/abcDS", "java:/abcDS", "abcDS". Which one is right? And is there some rule for this? I understand that it's related to JNDI, but...
I'm trying to create EMF in my unit test:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("abc");
This is what I'm getting in log:
[...]
SEVERE: Could not find datasource: abcDS javax.naming.NameNotFoundException:
Name "abcDS" not found.
at org.apache.openejb.core.ivm.naming.IvmContext.federate(IvmContext.java:193)
at org.apache.openejb.core.ivm.naming.IvmContext.lookup(IvmContext.java:150)
at org.apache.openejb.core.ivm.naming.ContextWrapper.lookup(ContextWrapper.java:115)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
[...]
The problem is that Persistence.createEntityManagerFactory("abc") is the "do it yourself" API and doesn't take advantage of the Embedded EJB Container. You can get a container managed EntityManager in your test case very easily.
Just as with the related jndi/datasource question I recommend you check out the examples in the examples.zip. They're all designed to take the struggle out of getting started.
Here's a snippet from the testcase-injection example which shows how you can get an EntityManager and other things from the container for use in a test.
First, add an empty ejb-jar.xml or application-client.xml to your test to turn on scanning for your test code:
src/test/resources/META-INF/application-client.xml
Then, annotate your test case with #org.apache.openejb.api.LocalClient and use the standard JavaEE annotations for the actual injection.
#LocalClient
public class MoviesTest extends TestCase {
#EJB
private Movies movies;
#Resource
private UserTransaction userTransaction;
#PersistenceContext
private EntityManager entityManager;
public void setUp() throws Exception {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
p.put("movieDatabase", "new://Resource?type=DataSource");
p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver");
p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb");
InitialContext initialContext = new InitialContext(p);
// Here's the fun part
initialContext.bind("inject", this);
}
As movieDatabase is the only DataSource that we've setup, OpenEJB will automatically assign that DataSource to your persistence unit without the need to modify your persistence.xml. You can even leave the <jta-data-source> or <non-jta-data-source> empty and OpenEJB will still know what to do.
But for the sake of completeness, here's how this particular application has defined the persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="movie-unit">
<jta-data-source>movieDatabase</jta-data-source>
<non-jta-data-source>movieDatabaseUnmanaged</non-jta-data-source>
<class>org.superbiz.testinjection.Movie</class>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
</properties>
</persistence-unit>
</persistence>
Then the fun part, using it all together in tests
public void test() throws Exception {
userTransaction.begin();
try {
entityManager.persist(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992));
entityManager.persist(new Movie("Joel Coen", "Fargo", 1996));
entityManager.persist(new Movie("Joel Coen", "The Big Lebowski", 1998));
List<Movie> list = movies.getMovies();
assertEquals("List.size()", 3, list.size());
for (Movie movie : list) {
movies.deleteMovie(movie);
}
assertEquals("Movies.getMovies()", 0, movies.getMovies().size());
} finally {
userTransaction.commit();
}
}

How to configure embedded OpenEJB container for tests properly?

This is my SLSB:
#Stateless
public class MyService {
PersistenceContext(unitName = "abc")
EntityManager em;
public boolean exists(int id) {
return this.em.find(Employee.class, id) != null;
}
}
This is my persistence.xml (I'm using Glassfish v3):
<persistence>
<persistence-unit name="abc">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MyDS</jta-data-source>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLInnoDBDialect" />
</properties>
</persistence-unit>
</persistence>
Now I'm trying to create a test, using OpenEJB embedded container. This is my test class:
class MyServiceText {
#Test
public void testChecksExistence() throws Exception {
Properties properties = new Properties();
properties.setProperty(
javax.naming.Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.LocalInitialContextFactory"
);
InitialContext ic = new InitialContext(properties);
// actual testing skipped
}
}
I would like to use HSQL for testing. How can I instruct OpenEJB that my persistence unit "abc" has to point to HSQL during testing? Shall I create a new version of persistence.xml? Shall I use openejb.xml? I'm lost in their examples and documentation.. :(
It's a Maven-3 project.
I would suggest placing a file named jndi.properties in src/test/resources for your OpenEJB configuration. This will then be available in the test classpath, you can then use the no-argument contructor of InitialContext to lookup datasources and ejbs. An example configuration looks like this, I'm using mysql for my datasource:
java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory
myDS=new://Resource?type=DataSource
myDS.JdbcDriver=com.mysql.jdbc.Driver
myDS.JdbcUrl=jdbc:mysql://127.0.0.1:3306/test
myDS.JtaManaged=true
myDS.DefaultAutoCommit=false
myDS.UserName=root
myDS.Password=root
OpenEJB should then automatically replace the reference in persistence.xml with this datasource, if this is the only datasource then this should work even if the names are different.
Edit: Persistence unit settings
According to the documentation you referenced it should also be possible to configure persistence unit properties through jndi.properties:
abc.hibernate.hbm2ddl.auto=update
abc.hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
I haven't tested this myself since I'm using mysql for both tests and normal executions, only with different database names. Please let me know if this works, I've been thinking about replacing mysql in my testcases too.

Categories

Resources