Table is not creating using JPA 2.0 - jpa-2.0

I am using JPA 2.0 in Netbeans. I am using entities. If my database has no table then it should create table from entities. Here is my code
public class BankServlet extends HttpServlet {
#EJB
private BankServiceBeanRemote bankServiceBean;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int custId = Integer.parseInt(request.getParameter("id"));
bankServiceBean.createCustomers();
Customer cust = bankServiceBean.findCustomer(custId);
response.setContentType("text/html;charset=UTF-8");
....
} //end of processRequest
} //end of class BankServlet
Here is my bean
#Stateless
public class BankServiceBean implements BankServiceBeanRemote {
#PersistenceContext(unitName = "Bank_JPA-ejbPU")
private EntityManager em;
#Override
public void createCustomers() {
Referee r1 = new Referee();
r1.setId(1);
r1.setName("SIR JOHN DEED");
r1.setComments("JUDGE");
em.persist(r1);
Customer c1 = new Customer();
c1.setId(1);
c1.setFirstName("SIMON");
c1.setLastName("KING");
c1.setReferee(r1);
......
}
} //end of class BankServiceBean
Here is my referee entity
#Entity
public class Referee implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
private String comments;
public Referee() {
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// other getter setters
} //end of class Referee
When i run the code i get following exception
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'dbbank.referee' doesn't exist
Error Code: 1146
Call: INSERT INTO REFEREE (ID, NAME, COMMENTS) VALUES (?, ?, ?)
bind => [3, MICHAEL ELLIS, MAJOR SHAREHOLDER OF THIS BANK]
Query: InsertObjectQuery(pk.mazars.basitMahmood.entity.Referee[id=3])
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
If table doesnot exist then it should create table automatically. Am i doing something wrong?
Thank you

Your assumptions are wrong. Tables are not magically created if they don't exist. Most of the applications use existing databases.
EclipseLink can create the schema for you, but it's not the default. Read this page to know how to enable this feature:
EclipseLink can be used to automatically generate the tables and
database schema for a persistence unit. This is done through the
"eclipselink.ddl-generation" persistence unit property, set to either
"create-tables" or "drop-and-create-tables". The tables and
constraints will be generated for all of the classes defined in that
persistence unit.

You should change your table generation strategy in persistence.xml.
just add these rows to the persistence.xml file :
<properties>
<property name="eclipselink.ddl-generation" value="create-tables"/>
</properties>

Here is a snippet to add to your persistence.xml to make openjpa create tables for you. This comes in handy when doing in container unit tests using openejb with an in memory database like HyperSQL.
<properties>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
</properties>

Related

Mockito: Mocking package private classes

I have the following simple DynamoDBDao which contains one method that queries an index and returns a map of results.
import com.amazonaws.services.dynamodbv2.document.*;
public class DynamoDBDao implements Dao{
private Table table;
private Index regionIndex;
public DynamoDBDao(Table table) {
this.table = table;
}
#PostConstruct
void initialize(){
this.regionIndex = table.getIndex(GSI_REGION_INDEX);
}
#Override
public Map<String, Long> read(String region) {
ItemCollection<QueryOutcome> items = regionIndex.query(ATTR_REGION, region);
Map<String, Long> results = new HashMap<>();
for (Item item : items) {
String key = item.getString(PRIMARY_KEY);
long value = item.getLong(ATTR_VALUE);
results.put(key, value);
}
return results;
}
}
I am trying to write a unit test which verifies that when the DynamoDB index returns an ItemCollection then the Dao returns the corresponding results map.
public class DynamoDBDaoTest {
private String key1 = "key1";
private String key2 = "key2";
private String key3 = "key3";
private Long value1 = 1l;
private Long value2 = 2l;
private Long value3 = 3l;
#InjectMocks
private DynamoDBDao dynamoDBDao;
#Mock
private Table table;
#Mock
private Index regionIndex;
#Mock
ItemCollection<QueryOutcome> items;
#Mock
Iterator iterator;
#Mock
private Item item1;
#Mock
private Item item2;
#Mock
private Item item3;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(table.getIndex(DaoDynamo.GSI_REGION_INDEX)).thenReturn(regionIndex);
dynamoDBDao.initialize();
when(item1.getString(anyString())).thenReturn(key1);
when(item1.getLong(anyString())).thenReturn(value1);
when(item2.getString(anyString())).thenReturn(key2);
when(item2.getLong(anyString())).thenReturn(value2);
when(item3.getString(anyString())).thenReturn(key3);
when(item3.getLong(anyString())).thenReturn(value3);
}
#Test
public void shouldReturnResultsMapWhenQueryReturnsItemCollection(){
when(regionIndex.query(anyString(), anyString())).thenReturn(items);
when(items.iterator()).thenReturn(iterator);
when(iterator.hasNext())
.thenReturn(true)
.thenReturn(true)
.thenReturn(true)
.thenReturn(false);
when(iterator.next())
.thenReturn(item1)
.thenReturn(item2)
.thenReturn(item3);
Map<String, Long> results = soaDynamoDbDao.readAll("region");
assertThat(results.size(), is(3));
assertThat(results.get(key1), is(value1));
assertThat(results.get(key2), is(value2));
assertThat(results.get(key3), is(value3));
}
}
My problem is that items.iterator() does not actually return Iterator it returns an IteratorSupport which is a package private class in the DynamoDB document API. This means that I cannot actually mock it as I did above and so I cannot complete the rest of my test.
What can I do in this case? How do I unit test my DAO correctly given this awful package private class in the DynamoDB document API?
First, unit tests should never try to verify private state internal to an object. It can change.
If the class does not expose its state via non-private getter methods, then it is none of your test's business how it is implemented.
Second, why do you care what implementation the iterator has?
The class has fulfilled its contract by returning an iterator (an interface)
which when iterated over will return the objects it is supposed to.
Third, why are you mocking objects that you don't need to?
Construct the inputs and outputs for your mocked objects, don't mock them; it is unnecessary.
You pass a Table into your constructor? Fine.
Then extend the Table class to make whatever protected methods for whatever you need.
Add protected getters and/or setters to your Table subclass.
Have them return hard coded values if necessary. They don't matter.
Remember, only test one class in your test class.
You are testing the dao not the table nor the index.
Dynamodb api has a lot of such classes which can not easily be mocked. This results in lot of time spent on writing complex tests and changing features are big pain.
I think, for this case a better approach will be not try to go the traditional way and use DynamodbLocal library by the AWS team - http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tools.DynamoDBLocal.html
This is basically an in memory implementation of DyanamoDB. We had written our tests such that during unit test initialization, DyanmodbLocal instance would be spawned and tables would be created. This makes the testing a breeze. We have not yet found any bugs in the library and it is actively supported and developed by AWS. Highly recommend it.
One possible workaround is to define a test class which extends IteratorSupport in the same package that it is present in, and define the desired behavior
You can then return an instance of this class through your mock setup in the test case.
Of course, this is not a good solution, but simply a workaround for the same reasons that #Jeff Bowman mentioned in the comment.
May be it'd be better to extract ItemCollection retrieval to the separate method?
In your case it may look as follows:
public class DynamoDBDao {
protected Iterable<Item> readItems(String region) { // can be overridden/mocked in unit tests
// ItemCollection implements Iterable, since ItemCollection-specific methods are not used in the DAO we can return it as Iterable instance
return regionIndex.query(ATTR_REGION, region);
}
}
then in unit tests:
private List<Item> mockItems = new ArrayList<>(); // so you can set these items in your test method
private DynamoDBDao dao = new DynamoDBDao(table) {
#Override
protected Iterable<Item> readItems(String region) {
return mockItems;
}
}
When you use when(items.iterator()).thenReturn(iterator); Mockito sees the items as ItemCollection which causes the compilation error. In your test case, you want to see ItemCollection as just an Iterable. So, the simple solution is to cast the items as Iterable like below:
when(((Iterable<QueryOutcome>)items).iterator()).thenReturn(iterator);
Also make your iterator as
#Mock
Iterator<QueryOutcome> iterator;
This should fix the code without warning :)
If this fixes the problem, please accept the answer.
You can test your read method by using fake objects like this :
public class DynamoDBDaoTest {
#Mock
private Table table;
#Mock
private Index regionIndex;
#InjectMocks
private DynamoDBDao dynamoDBDao;
public DynamoDBDaoTest() {
}
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(table.getIndex(GSI_REGION_INDEX)).thenReturn(regionIndex);
dynamoDBDao.initialize();
}
#Test
public void shouldReturnResultsMapWhenQueryReturnsItemCollection() {
when(regionIndex.query(anyString(), anyString())).thenReturn(new FakeItemCollection());
final Map<String, Long> results = dynamoDBDao.read("region");
assertThat(results, allOf(hasEntry("key1", 1l), hasEntry("key2", 2l), hasEntry("key3", 3l)));
}
private static class FakeItemCollection extends ItemCollection<QueryOutcome> {
#Override
public Page<Item, QueryOutcome> firstPage() {
return new FakePage();
}
#Override
public Integer getMaxResultSize() {
return null;
}
}
private static class FakePage extends Page<Item, QueryOutcome> {
private final static List<Item> items = new ArrayList<Item>();
public FakePage() {
super(items, new QueryOutcome(new QueryResult()));
final Item item1= new Item();
item1.with(PRIMARY_KEY, "key1");
item1.withLong(ATTR_VALUE, 1l);
items.add(item1);
final Item item2 = new Item();
item2.with(PRIMARY_KEY, "key2");
item2.withLong(ATTR_VALUE, 2l);
items.add(item2);
final Item item3 = new Item();
item3.with(PRIMARY_KEY, "key3");
item3.withLong(ATTR_VALUE, 3l);
items.add(item3);
}
#Override
public boolean hasNextPage() {
return false;
}
#Override
public Page<Item, QueryOutcome> nextPage() {
return null;
}
}
ItemCollection<QueryOutcome> items = new ItemCollection<QueryOutcome>() {
#Override
public Integer getMaxResultSize() {
return 0;
}
#Override
public Page<Item, QueryOutcome> firstPage() {
return null;
}
};
Mockito.when(index.query(Mockito.any(QuerySpec.class))).thenReturn(items);
QueryResult queryResult = new QueryResult();
Mockito.when(dynamoDBClient.query(Mockito.any(QueryRequest.class))).thenReturn(queryResult);

spring-data-neo4j in "Advanced Mapping" mode - How can I read an entity-value without starting a transaction manually?

In my JavaEE7-project, I am using spring-data-neo4j standalone in "Advanced Mapping" mode (using spring-aspects). Everything works fine so far: CRUD on entities within a transaction, where the transaction is started manually or via #Transactional-annotation.
In my usecase, my view accesses an entity "directly":
// User
#NodeEntity
public class User {
private String firstName;
// getter, setter, ...
}
// SessionBean
#SessionScoped
#Named
public class SessionBean {
#Transactional
public User getUser() {
User user = ...;
System.out.println(user.getFirstName()); // (1) gives firstName-value.
return user;
}
}
// sometpl.xhtml
${sessionBean.user.firstName} // (2) gives "null".
Somehow, this behavior (difference between (1) and (2)) is wanted, as spring-data-neo4j supposes read-access only within a transaction.
But I want to have my usecase(2) working (returning the user's firstName, not "null"). Is there any way to achieve this? So let's say, starting transaction automatically in read-access-case? Implicit read-transactions-support?
My workaround:
Use a RequestScoped bean to start a transaction in "preRenderView" and to close this tx when the bean is destroyed.
This does not work on ajax-calls!
#Named
#RequestScoped
public class SpringDataNeo4jHelperBean {
#Inject
#Named
private Neo4jTemplate neoTemplate;
private Transaction tx;
#PreDestroy
public void finishTransaction() {
if (this.tx != null) {
this.tx.success();
this.tx.finish();
}
}
public void startReadOnlyTransaction() {
if (!this.neoTemplate.getGraphDatabase().transactionIsRunning()) {
this.tx = this.neoTemplate.getGraphDatabaseService().beginTx();
}
}
}
In some template, for example s.th. like a central layout.xhtml:
<f:metadata>
<f:event type="preRenderView" listener="#{springDataNeo4jHelperBean.startReadOnlyTransaction()}" />
</f:metadata>

ConstraintViolationException in Java RESTful Webservice

I'm relatively new to JavaEE and web services, however, I'm using netbeans to generate my client and webservice resources. I have a resource "CustomerData" that represents a mysql database table and a value "rewardsPoints" representing a column in that table, however, I am unable to update the value due to a ConstraintViolationException, specifically:
javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'preUpdate'. Please refer to embedded ConstraintViolations for details.
I'm not familiar with the 'preUpdate' callback event, is it something I need to override? I can't seem to figure out exactly why this exception is being thrown, but, as I said, i'm very new to web service programming. Here are my classes:
#Stateless
#Path("customers")
public class CustomerDataFacadeREST extends AbstractFacade<CustomerData> {
#PersistenceContext(unitName = "CustomerPortalPU")
private EntityManager em;
public CustomerDataFacadeREST() {
super(CustomerData.class);
}
#PUT
#Path("{id}")
#Consumes({"application/xml", "application/json"})
public void edit(#PathParam("id") Integer id, CustomerData entity) {
super.edit(entity);
}
#GET
#Path("{id}")
#Produces({"application/xml", "application/json"})
public CustomerData find(#PathParam("id") Integer id) {
return super.find(id);
}
#GET
#Path("addPoints/{id}/{amount}")
#Produces({"text/plain"})
public String addPoints(#PathParam("id") Integer id, #PathParam("amount") int amount) {
CustomerData customer = find(id);
customer.getRewardsPoints(customer.getRewardsPoints() + amount);
em.persist(customer);
edit(customer);
return customer.getRewardsPoints();
}
#Override
protected EntityManager getEntityManager() {
return em;
}
}
And the CustomerData entity class:
#Entity
#Table(name = "tbl_customer_data")
#XmlRootElement
public class CustomerData implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Column(name = "rewards_points")
private int rewardsPoints;
public CustomerData(Integer id, int rewardsPoints) {
this.id = id;
this.rewardsPoints = rewardsPoints;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public int getRewardsPoints() {
return rewardsPoints;
}
public void setRewardsPoints(int rewardsPoints) {
this.rewardsPoints = rewardsPoints;
}
}
When I try to access the URI:
http://localhost:8080/CustomerPortal/ws/customers/addPoints/1/5
to add 5 points to user with id 1 i get an HTTP 500 error and in the glassfish logs it says
[2013-11-05T03:28:11.733-0500] [glassfish 4.0] [WARNING] [ejb.system_exception] [javax.enterprise.system.container.ejb.com.sun.ejb.containers] [tid: _ThreadID=21 _ThreadName=http-listener-1(3)] [timeMillis: 1383640091733] [levelValue: 900] [[
EJB5184:A system exception occurred during an invocation on EJB CustomerDataFacadeREST, method: public java.lang.String com.webservice.entities.CustomerDataFacadeREST.addPoints(java.lang.Integer,int)]]
[2013-11-05T03:28:11.741-0500] [glassfish 4.0] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=21 _ThreadName=http-listener-1(3)] [timeMillis: 1383640091741] [levelValue: 900] [[
StandardWrapperValve[com.webservice.entities.ApplicationConfig]: Servlet.service() for servlet com.webservice.entities.ApplicationConfig threw exception
javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'preUpdate'. Please refer to embedded ConstraintViolations for details.
Any resources, insight or information regarding this issue would be extremely helpful.
The exception has little to do with web services: it has to do with Bean Validation instead.
In this case, since the Validation fails inside method addPoints (look at the stack trace) the only line that can cause it is when persisting or editing an Entity of type CustomerData. The only constraint you have in that class is that rewardsPoints should not be null. So, that's the cause of the exception.
However there some things that won't work in addPoints method:
You should check that find() method doesn't return a null object.
customer.getRewardsPoints(customer.getRewardsPoints() + amount) never sets the property (does it compile?)
EntityManager.persist() throws exception if the entity already exists. You probably want to remove that line if you only want to edit (update) the entity.
Note: I am not sure that the code you have posted is really compiling and causing that exception. That's probably caused by another version.

Trouble with my first RESTful Web Services

i'm developing my firts RestFul webServices in javaEE6.
This is my Entity Bean
#XmlRootElement
#Entity
public class MyEntity implements Serializable {
#Id
#GeneratedValue
private long idEntity;
private String name;
private String description;
#OneToMany(mappedBy = "entity" , fetch = FetchType.EAGER)
private List<EntityB> list;
//Get and set
}
#Entity
public class EntityB {
#Id
#GeneratedValue
private long idCategoria;
#ManyToOne
private MyEntity myEntity;
}
this is my webServices
#Path("myentity")
#Produces( {MediaType.APPLICATION_XML , MediaType.APPLICATION_JSON })
#Consumes( {MediaType.APPLICATION_XML , MediaType.APPLICATION_JSON })
#Stateless
public class MyEntityService {
#Inject
MyEntityDao entityDao;
#GET
#Path("{id}/")
public MyEntity findById(#PathParam("id") Long id){
return entityDao.findById(id);
}
}
Finally i configured Jersey
#ApplicationPath("ws")
public class ApplicationConfig extends Application {
}
Now , if i try a invoke my web services (localhost:8080/xxxx/ws/myentity) i get this error:
HTTP Status 500 - javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2: A cycle is detected in the object graph. This will cause infinitely deep XML
You have a cyclic Graph of objects, which is not allowed , as it would result in an "infinite" XML.
MyEntity Holds a reference to EntityB , which holds a reference that goes back to MyEntity.
The marshaller will try to marshall MyEntity > EntityB > MyEntity > EntityB and so on.
You can mark MyEntity in EntityB as #XmlTransient, to avoid this.
However, It might not be a good idea to try to use the same Classes of objects across all your project (From persistence layers to communication layers).

How to use JUnit with EJB3 and JPA

I'm trying to test my Session Beans with JUnit, but I can't. I've tried a lot of method, but still get some exceptions.
Here is what I need:
I have a few Stateless Session Beans I need to test. Each has the same #PersistenceContext and uses an EntityManager
With my test cases I need to test their methods. For instance: if I add an user with username X and then I try to add another one with the same username, I want to catch an Exception.
Can someone provide a simple and short generic test example? I've already read many, but I always get an error (I get NullPointerException for the EntityManager when I call a method like: sessionBean.method() (which does, for instance, entityManager.find(...)), or I am not able to initialize the Context, or other PersistenceException).
You might be interested in one of the latest posts of Antonio Goncalves:
WYTIWYR : What You Test Is What You Run
It tells about testing EJB with EntityManager using:
Mockito,
Embedded EJB Container,
Arquillian.
I solved creating a Stateless Session Bean and injecting its Entity Manager to test classes. I post the code in case someone will need it:
#Stateless(name = "TestProxy")
#Remote({TestProxyRemote.class})
public class TestProxy implements TestProxyRemote {
#PersistenceContext(unitName = "mph")
private EntityManager em;
#Override
public void persist(Object o) {
em.persist(o);
}
#Override
public void clear() {
em.clear();
}
#Override
public void merge(Object o) {
em.merge(o);
}
#Override
#SuppressWarnings({ "rawtypes", "unchecked" })
public Object find(Class classe, String key) {
return em.find(classe, key);
}
#Override
#SuppressWarnings({ "rawtypes", "unchecked" })
public Object find(Class classe, long key) {
return em.find(classe, key);
}
#SuppressWarnings("rawtypes")
#Override
public List getEntityList(String query) {
Query q = em.createQuery(query);
return q.getResultList();
}
}
public class MyTest {
#BeforeClass
public static void setUpBeforeClass() throws NamingException {
Properties env = new Properties();
env.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.setProperty(Context.PROVIDER_URL, "localhost:1099");
env.setProperty("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
jndiContext = new InitialContext(env);
try {
proxy = (TestProxyRemote) jndiContext.lookup("TestProxy/remote");
} catch (NamingException e) {
e.printStackTrace();
}
}
}
Then I can use proxy.find() to get the entities I need, o proxy.getEntityList() to execute a query to retrieve all the instance of an Entity. Or I can add other methods if I want.
Unitils provides a really cool support for JPA. Unitils can be used with JUnit or TestNG and in case you need a mocking framework, Unitils provides its own mocking module as well as support for EasyMock.
#JpaEntityManagerFactory(persistenceUnit = "testPersistenceUnit")
#DataSet(loadStrategy = RefreshLoadStrategy.class)
public class TimeTrackerTest extends UnitilsTestNG {
#TestedObject
private TimeTrackerBean cut = new TimeTrackerBean();
#InjectInto(target="cut",property="em")
#PersistenceContext
private EntityManager em;
#Test
#DataSet("TimeTrackerTest.testAddTimeSlot.xml")
public void yourTest() {
...
}
}
#JpaEntityManagerFactory - Used to specify your persistence unit. It automatically picks up the persistence.xml from your project classpath.
#DataSet - Just in case you need to load any test data you can use this.
#TestedObject - Marks your Class Under Test
#PersistenceContext - Automatically creates your EntityManager instance from the configurations made in the persistence.xml - PersistenceUnit.
#InjectInto - Injects the em instance into the target (cut)
For more information refer this.
Hope this helps.
I'm using Needle for this. It works well with Mockito and EasyMock if you want to mock other objects.
First I write a persistencte.xml for tests (src/test/resources/META-INF) like this:
<persistence-unit name="rapPersistenceTest" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:~/test"/>
...
</properties>
</persistence-unit>
In my Junit-Testclass I write:
public class DaoNeedleTest {
//here Needle will create persistenceContext for your testclass
public static DatabaseRule databaseRule = new DatabaseRule("rapPersistenceTest");
//here you can get the entityManager to manipulate data directly
private final EntityManager entityManager = databaseRule.getEntityManager();
#Rule
public NeedleRule needleRule = new NeedleRule(databaseRule);
//here you can instantiate your daoService
#ObjectUnderTest
DAOService daoService;
#Test
public void test() {
//if your method needs a transaction here you can get it
entityManager.getTransaction().begin();
daoService.yourMethod();
entityManager.getTransaction().commit();
}
You also need a Needle-configuration File in src/test/resources, where you tell what kind of Mock-provider you are using. E.g. I'm using Mockito:
mock.provider=de.akquinet.jbosscc.needle.mock.MockitoProvider
That's it.