EntityManager and createEntityManagerFactory with application.properties - java

I have to create singleton classes using DAO classes.
Following is a DAO reading class example:
package com.luiz.teste.dao;
import com.luiz.teste.exceptions.postgres.ReadSubjectDaoFindException;
import org.eclipse.microprofile.opentracing.Traced;
import javax.enterprise.context.RequestScoped;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.PersistenceException;
#Traced
#ApplicationScoped
public class ReadSubjectDao {
private static ReadSubjectDao instance = new ReadSubjectDao();
protected EntityManager em;
public static ReadSubjectDao getInstance() {
return instance;
}
private ReadSubjectDao() {
if (em == null) {
em = Persistence.createEntityManagerFactory("postgres").createEntityManager();
}
}
public ReadSubject findById(int id) throws ReadSubjectDaoFindException {
try {
return em.find(ReadSubject.class, id);
}
catch (NoResultException e) {
return null;
}
catch (PersistenceException e) {
throw new ReadSubjectDaoFindException(e);
}
}
}
Following is a DAO writing class example:
package com.luiz.teste.dao;
import com.luiz.teste.exceptions.mysql.WriteSubjectDaoFindException;
import com.luiz.teste.exceptions.mysql.WriteSubjectDaoPersistException;
import com.luiz.teste.exceptions.mysql.WriteSubjectDaoMergeException;
import org.eclipse.microprofile.opentracing.Traced;
import javax.enterprise.context.RequestScoped;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.PersistenceException;
#Traced
#ApplicationScoped
public class WriteSubjectDao {
private static WriteSubjectDao instance = new WriteSubjectDao();
protected EntityManager em;
public static WriteSubjectDao getInstance() {
return instance;
}
private WriteSubjectDao() {
if (em == null) {
em = Persistence.createEntityManagerFactory("mysql").createEntityManager();
}
}
public WriteSubject findById(int id) throws WriteSubjectDaoFindException {
try {
return em.find(WriteSubject.class, id);
}
catch (NoResultException e) {
return null;
}
catch (PersistenceException e) {
throw new WriteSubjectDaoFindException(e);
}
}
public void persist(WriteSubject writeSubject) throws WriteSubjectDaoPersistException {
EntityTransaction et = em.getTransaction();
try {
et.begin();
em.persist(writeSubject);
et.commit();
}
catch (Exception e) {
if (et.isActive())
et.rollback();
throw new WriteSubjectDaoPersistException(e);
}
}
public void merge(WriteSubject writeSubject) throws WriteSubjectDaoMergeException {
EntityTransaction et = em.getTransaction();
try {
et.begin();
em.merge(writeSubject);
et.commit();
}
catch (Exception e) {
if (et.isActive())
et.rollback();
throw new WriteSubjectDaoMergeException(e);
}
}
}
Following is application.properties:
# Configuration file
# key = value
quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %X{requestID} %s%e%n
mp.metrics.tags=app=${quarkus.application.name},version=${quarkus.application.version}
%test.mp.metrics.tags=app=app-test,version=1.0.0
mp.openapi.filter=com.luiz.teste.dev.ext.filters.OpenApiFilter
quarkus.swagger-ui.path=/api-docs
quarkus.smallrye-openapi.path=/api-docs-json
quarkus.swagger-ui.always-include=true
quarkus.http.test-port=8083
quarkus.http.test-ssl-port=8446
quarkus.datasource.jdbc.enable-metrics=true
# Postgre - Build time
quarkus.datasource."postgres".db-kind=db2
quarkus.datasource."postgres".jdbc.url=${POSTGRE_JDBC}
quarkus.datasource."postgres".username=${POSTGRE_USER}
quarkus.datasource."postgres".password=${POSTGRE_PASSWORD}
quarkus.hibernate-orm."postgres".datasource=postgres
quarkus.hibernate-orm."postgres".packages=com.luiz.teste.models.postgres
quarkus.hibernate-orm."postgres".log.jdbc-warnings=false
quarkus.hibernate-orm."postgres".log.sql=true
# MySQL - Build time
quarkus.datasource."mysql".db-kind=mysql
quarkus.datasource."mysql".jdbc.url=${MYSQL_JDBC}
quarkus.datasource."mysql".username=${MYSQL_USER}
quarkus.datasource."mysql".password=${MYSQL_PASSWORD}
quarkus.hibernate-orm."mysql".datasource=mysql
quarkus.hibernate-orm."mysql".packages=com.luiz.teste.models.mysql
quarkus.hibernate-orm."mysql".log.jdbc-warnings=false
quarkus.hibernate-orm."mysql".log.sql=true
As far as I've searched through this site (and through https://www.google.com too), I know so far only by using persistence.xml.
How to achieve the same result using only the application.properties when calling createEntityManagerFactory?
UPDATE (2022-01-03): As requested, changed from #RequestScoped to #ApplicationScoped and changed from postgre to postgres.

Finally found a solution to this issue, after searching lots here and googling for any answer.
Instead of manually creating instance field on those classes, to make singleton classes within Quarkus you shall use #Singleton annotation.
Fixed ReadSubjectDao.java:
package com.luiz.teste.dao.postgres;
import com.luiz.teste.exceptions.postgres.ReadSubjectDaoFindException;
import org.eclipse.microprofile.opentracing.Traced;
import javax.inject.Singleton;
import javax.inject.Inject;
import io.quarkus.hibernate.orm.PersistenceUnit;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceException;
#Traced
#Singleton
public class ReadSubjectDao {
#Inject
#PersistenceUnit("postgres")
EntityManager em;
public ReadSubject findById(int id) throws ReadSubjectDaoFindException {
try {
return em.find(ReadSubject.class, id);
}
catch (NoResultException e) {
return null;
}
catch (PersistenceException e) {
throw new ReadSubjectDaoFindException(e);
}
}
}
Fixed WriteSubjectDao.java:
package com.luiz.teste.dao.mysql;
import com.luiz.teste.exceptions.mysql.WriteSubjectDaoFindException;
import com.luiz.teste.exceptions.mysql.WriteSubjectDaoPersistException;
import com.luiz.teste.exceptions.mysql.WriteSubjectDaoMergeException;
import org.eclipse.microprofile.opentracing.Traced;
import javax.inject.Singleton;
import javax.inject.Inject;
import io.quarkus.hibernate.orm.PersistenceUnit;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceException;
import javax.transaction.Transactional;
#Traced
#Singleton
public class WriteSubjectDao {
#Inject
#PersistenceUnit("mysql")
EntityManager em;
public WriteSubject findById(int id) throws WriteSubjectDaoFindException {
try {
return em.find(WriteSubject.class, id);
}
catch (NoResultException e) {
return null;
}
catch (PersistenceException e) {
throw new WriteSubjectDaoFindException(e);
}
}
#Transactional
public void persist(WriteSubject writeSubject) throws WriteSubjectDaoPersistException {
try {
em.persist(writeSubject);
}
catch (Exception e) {
throw new WriteSubjectDaoPersistException(e);
}
}
#Transactional
public void merge(WriteSubject writeSubject) throws WriteSubjectDaoMergeException {
try {
em.merge(writeSubject);
}
catch (Exception e) {
throw new WriteSubjectDaoMergeException(e);
}
}
}
The application.properties remain unchanged.
To call any of those 2 singleton DAO classes, just use #Inject annotation on caller classes, as usual.

Your pattern is extremely weird.
If you want a singleton DAO, just use #ApplicationScoped for the scope of your DAO. Don't make it #RequestScoped and then have a static instance, it's going to be broken.
Then, with Quarkus, you shouldn't create the EntityManagerFactory yourself. You can just inject an EntityManager with:
#Inject
#PersistenceUnit("postgre")
EntityManager entityManager;
and you're done.

Related

Should EntityManagerFactory be closed at application shutdown?

I have a Java application that has a GUI made with Swing and that uses two databases interchangeably. One of the two databases is mongoDB and the other one is MySQL. Which database to use is chosen with a command line option. For the MySQL database I am also using Hibernate and JPA. The code I have looks like this:
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import java.awt.EventQueue;
import java.util.concurrent.Callable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
#Command(mixinStandardHelpOptions = true)
public class App implements Callable<Void> {
private static final Logger LOGGER = LogManager.getLogger(App.class);
#Option(names = { "--database" }, description = "'mongo' or 'mysql'")
private String databaseType = "mysql";
public static void main(String[] args) {
new CommandLine(new App()).execute(args);
}
#Override
public Void call() throws Exception {
EventQueue.invokeLater(() -> {
switch (databaseType) {
case "mysql":
EntityManagerFactory emf;
EntityManager entityManager;
try {
emf = Persistence.createEntityManagerFactory("name");
entityManager = emf.createEntityManager();
// other stuff
} catch (Exception e) {
LOGGER.log(Level.ERROR, "MySQL Exception", e);
}
break;
case "mongo":
// mongo stuff, no EntityManagerFactory here
break;
default:
LOGGER.log(Level.ERROR, "--database must be either 'mysql' or 'mongo'");
System.exit(1);
}
//...
try {
View view = new View();
view.setVisible(true);
} catch (Exception e) {
LOGGER.log(Level.ERROR, "Exception", e);
}
});
return null;
}
In mysql case I am creating an EntityManagerFactory and an EntityManager. The entityManager created here is passed as argument to the constructor of the repositories and used throughout the whole life of the application.
I was wondering what is the best practice about closing the entityManager and the factory.
Searching in the documentation I found this:
Closing an EntityManagerFactory should not be taken lightly. It is
much better to keep a factory open for a long period of time than to
repeatedly create and close new factories. Thus, most applications
will never close the factory, or only close it when the application is
exiting.
So I was wondering, what is the difference between closing the factory and entity manager at application shutdown and not closing it? Also in my case I'm declaring emf and entityManager inside the mysql case since are not required for mongodb. In order to close them at application shutdown what should I do? I found something about Runtime.getRuntime().addShutdownHook(). I tried using it like the code below, but it seems like it is not working.
try {
emf = Persistence.createEntityManagerFactory("name");
entityManager = emf.createEntityManager();
Thread closeHook = new Thread(() -> {
if (emf != null) {
entityManager.close();
emf.close();
LOGGER.log(Level.INFO, "Close entity manager and entity manager factory");
}
});
Runtime.getRuntime().addShutdownHook(closeHook);
// other stuff
} catch (Exception e) {
LOGGER.log(Level.ERROR, "MySQL Exception", e);
}
Short answer, yes, it should be closed. And the reason can be found at this answer:
The JVM will release all active resources upon termination; however, this does not ensure that the other end will free the resource too, so explicitly closing resources is in every programmer's best interest.
So in my case, it is true that the EntityManager and factory are closed at application shutdown, but this does not ensure that they are properly dealt with on the other end.
I didn't mention it in my question, but in fact the same thing holds true for the Mongo Client as well (see this answer):
If you ever re-deploy your web application without first restarting your application server, you must ensure that the MongoClient is closed when your web application is shutdown.
About the implementation I made an interface that I called DBInitializer. I instantiated an object of type MongoInitializer or MySQLInitializer (both implementing DBInitializer) inside the main method. See code for more clarity.
DBInitializer:
public interface DBInitializer {
public void startDbConnection();
public void closeDbConnection();
}
MySQLInitializer:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class MySQLInitializer implements DBInitializer {
private EntityManagerFactory emf;
private EntityManager entityManager;
private final Logger logger = LogManager.getLogger(MySQLInitializer.class);
#Override
public void startDbConnection() {
try {
emf = Persistence.createEntityManagerFactory("name");
entityManager = emf.createEntityManager();
// other stuff
} catch (Exception e) {
logger.log(Level.ERROR, "MySQL Exception", e);
}
}
#Override
public void closeDbConnection() {
if (emf != null) {
entityManager.close();
emf.close();
}
}
}
MongoInitializer:
import com.mongodb.MongoClient;
import com.mongodb.ServerAddress;
public class MongoInitializer implements DBInitializer {
private MongoClient client;
private final Logger logger = LogManager.getLogger(MongoInitializer.class);
#Override
public void startDbConnection() {
try {
client = new MongoClient(new ServerAddress("localhost", 27017));
// other stuff
} catch (Exception e) {
logger.log(Level.ERROR, "Mongo Exception", e);
}
}
#Override
public void closeDbConnection() {
client.close();
}
}
App:
import java.awt.EventQueue;
import java.util.concurrent.Callable;
import DBInitializer;
import MongoInitializer;
import MySQLInitializer;
import View;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
#Command(mixinStandardHelpOptions = true)
public class App implements Callable<Void> {
private static final Logger LOGGER = LogManager.getLogger(App.class);
#Option(names = { "--database" }, description = "Either 'mongo' or 'mysql'")
private String databaseType = "mysql";
public static void main(String[] args) {
new CommandLine(new App()).execute(args);
}
DBInitializer dBInitializer;
#Override
public Void call() throws Exception {
EventQueue.invokeLater(() -> {
try {
switch (databaseType) {
case "mysql":
dBInitializer = new MySQLInitializer();
break;
case "mongo":
dBInitializer = new MongoInitializer();
break;
default:
LOGGER.log(Level.ERROR, "--database must be either 'mysql' or 'mongo'");
System.exit(1);
}
dBInitializer.startDbConnection();
// other stuff
View view = new View();
view.setVisible(true);
} catch (Exception e) {
LOGGER.log(Level.ERROR, "Exception", e);
}
});
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
dBInitializer.closeDbConnection();
}
});
return null;
}
}
what is the difference between closing the factory and entity manager at application shutdown and not closing it?
A potential resource leak (e.g. an unclosed connection pool) vs lack thereof. Also:
I tried using it like the code below, but it seems like it is not working.
Why not use a try-with-resources statement?

Mockito Exception Handling Issue

I have the following class,
public class Processor {
JobUpdate jobUpdate = new JobUpdate();
public void process(Job job){
try {
doProcess(job);
}catch (Exception e){
handleError(job);
System.out.println("This is error");
throw e; // Here throw Runtime Exception.
}
}
private void handleError(Job job) {
if (job.getFailure() > 0){
jobUpdate.updateJobStatus(job, JobStatus.SUBMITTED);
}else{
jobUpdate.updateJobStatus(job, JobStatus.FAILED);
}
}
private void doProcess(Job job){
String name = job.getName();
name += "added";
// ....
}
}
and my test cases as below,
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
#ExtendWith(MockitoExtension.class)
public class ProcessTest {
Processor processor = new Processor();
#Mock
private Job job;
#Mock
private JobUpdate jobUpdate;
#Captor
private ArgumentCaptor<Job> captorJob;
#Captor
private ArgumentCaptor<JobStatus> captorStatus;
#Test
public void shouldThrowException(){
Mockito.when(job.getName()).thenThrow(RuntimeException.class);
Mockito.when(job.getFailure()).thenReturn(2);
processor.process(job);
Mockito.verify(jobUpdate).updateJobStatus(captorJob.capture(),captorStatus.capture());
assertThat(captorJob.getValue().getFailure(), equalTo( 2));
assertThat(captorStatus.getValue(), equalTo( JobStatus.SUBMITTED));
}
}
The flow goes fine in catch block and after executing System.out.println("This is error"); statement, it throws exception. The controller not backing to test class to verify my ArgumentCaptor.
am i missing something or need to be changed?

Why I can't detect annotations from a loaded java class?

I have a plugin within i want to access to the class list of my model package from my maven project. Until now i just did this to load the classes into the plugin :
try {
runtimeClasspathElements = project.getRuntimeClasspathElements();
} catch (DependencyResolutionRequiredException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
URL[] runtimeUrls = new URL[runtimeClasspathElements.size()];
for (int i = 0; i < runtimeClasspathElements.size(); i++) {
String element = (String) runtimeClasspathElements.get(i);
try {
runtimeUrls[i] = new File(element).toURI().toURL();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
newLoader = new URLClassLoader(runtimeUrls,
Thread.currentThread().getContextClassLoader());
try { class=newLoader.loadClass("com.pkl.bc.personnaldata.model.Personne");
if(class!=null)
System.out.println(class.getCanonicalName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Until here i can see the full name of my class.
System.out.println(class.getDeclaredFields());
System.out.println(class.isAnnotationPresent(EditColumn.class));
for (Field f : class.getDeclaredFields()) {
EditColumn v = f.getAnnotation(EditColumn.class);
if (v != null) {
System.out.println(v.tableName());
System.out.println(v.oldName());
}
}
but i don't get anything, here is the output :
[Ljava.lang.reflect.Field;#398f573b
false
I also tried to use refelctions
Reflections reflections = new Reflections("com.pkl.bc.personnaldata.model.Personne");
Set<Field> annotated = reflections.getFieldsAnnotatedWith(EditColumn.class);
System.out.println(annotated);
this give me an empty list.
here is my annotation :
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.FIELD})
public #interface EditColumn {
String oldName() default "";
String newName() default "";
String tableName() default "";
}
the annotated field :
#EditColumn(newName = "main_adress", oldName = "adress", tableName = "Personne")
private String main_adress;
I fixed my answer,that your problem is loading different class instance in different ClassLoader when Thread.getContextClassLoader() returns null,because URLClassLoader(urls,parent) when parent is null.you can see the tests that both ways java return a Proxy instance for Annotation Name instance.occurs this problem often someone calls Thread.currentThread().setContextClassLoader(null) in somewhere.so you can solve the problem by checking the contextLoader whether is null.for example:
ClassLoader context=Thread.currentThread().getContextClassLoader();
if(context==null){
context=getClass().getClassLoader();
}
URLClassLoader loader=new URLClassLoader(urls,context);
Test
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Stream;
import static java.lang.String.format;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
/**
* Created by holi on 3/24/17.
*/
public class AnnotationsTest {
private interface StubClass {
Class<?> stubClass() throws ClassNotFoundException;
default <T extends Annotation> T annotation(Class<T> type) throws Exception {
return stubClass().getAnnotation(type);
}
default Annotation[] annotations() throws Exception {
return stubClass().getAnnotations();
}
}
private static final StubClass JAR_WITHIN_ANNOTATION_CLASS = jar("stubs-within-annotation-class.jar");
private static final StubClass JAR_WITHOUT_ANNOTATION_CLASS = jar("stubs-without-annotation-class.jar");
public static StubClass jar(String jar) {
URL jarFile = Objects.requireNonNull(ClassLoader.getSystemResource(jar), format("Jar file not found:%s", jar));
return () -> {
ClassLoader context = Thread.currentThread().getContextClassLoader();
return new URLClassLoader(new URL[]{jarFile}, context).loadClass("Stub");
};
}
private ClassLoader original;
#BeforeEach
void setUp() throws Throwable {
original = Thread.currentThread().getContextClassLoader();
}
#AfterEach
void tearDown() throws Throwable {
Thread.currentThread().setContextClassLoader(original);
}
#Test
void getAnnotationFromJarClassesWillReturnsContextLoaderAnnotationSharedInstanceIfContextLoaderAssociatedWithRuntimeClassLoader() throws Throwable {
Set<Object> annotationsCreated = new HashSet<>();
Set<Object> stubClassCreated = new HashSet<>();
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
Stream.of(JAR_WITHIN_ANNOTATION_CLASS, JAR_WITHOUT_ANNOTATION_CLASS).forEach(asserts(stub -> {
Name it = stub.annotation(Name.class);
assertThat(it, is(instanceOf(Name.class)));
assertThat(it.value(), equalTo("stub"));
annotationsCreated.add(it);
stubClassCreated.add(stub.stubClass());
}));
assertThat(annotationsCreated, hasSize(1));
assertThat(stubClassCreated, hasSize(2));
}
#Test
void getAnnotationFromJarClassesWillReturnsNullIfNoContextLoaderAssociated() throws Throwable {
Thread.currentThread().setContextClassLoader(null);
Stream.of(JAR_WITHIN_ANNOTATION_CLASS, JAR_WITHOUT_ANNOTATION_CLASS).forEach(asserts(it -> {
//create different class instance in each class loader
assertThat(it.stubClass().getName(), equalTo("Stub"));
assertThat(it.annotation(Name.class), is(nullValue()));
}));
assertThat(JAR_WITHOUT_ANNOTATION_CLASS.annotations(), is(emptyArray()));
assertThat(JAR_WITHIN_ANNOTATION_CLASS.annotations(), arrayWithSize(1));
Annotation it = JAR_WITHIN_ANNOTATION_CLASS.annotations()[0];
assertThat(it.annotationType(), is(not(instanceOf(Name.class))));
assertThat(it.annotationType().getName(), equalTo(Name.class.getName()));
assertThat(it.annotationType().getDeclaredMethod("value").invoke(it), equalTo("stub"));
}
private interface Assert<T> {
void assertThat(T value) throws Exception;
}
private <T> Consumer<T> asserts(Assert<T> executor) {
return (value) -> {
try {
executor.assertThat(value);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
RuntimeException wrappedException = new RuntimeException(e);
wrappedException.setStackTrace(e.getStackTrace());
throw wrappedException;
}
};
}
}
#Name Annotation
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Created by holi on 3/24/17.
*/
#Retention(RetentionPolicy.RUNTIME)
public #interface Name {
String value();
}
Stub class
#Name("stub")
public class Stub{
}
You are already retrieving the class with its annotations , but you just need to add a loop to itirate all the annotations for each field you have.
try this example , it will print the annotation name and its values when it is available for a field of the loaded class.
for (Field f : loadedClass.getDeclaredFields()) {
System.out.println(f.getName());
for (Annotation a : f.getAnnotations()) {
System.out.println("## SHOWING ANNOTATION FOR FIELD:" + f.getName());
System.out.println(a.toString());
}
}
You can parse the toString to retrieve the values on that annotation.
Waiting for you feedback.

#autowire annotation not working

I have a controller GGSNAcceptController.java:
package com.viettel.pcrf.controller;
import com.viettel.fw.Exception.LogicException;
import com.viettel.fw.dto.BaseMessage;
import com.viettel.fw.web.controller.BaseController;
import com.viettel.pcrf.common.Const;
import com.viettel.pcrf.dto.GgsnAcceptDTO;
import com.viettel.pcrf.webconfig.service.GgsnAcceptService;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component
#ManagedBean(name = "ggsnAcceptController")
#Scope("view")
public class GGSNAcceptController extends BaseController implements Serializable, BaseTableCTRL {
/**
* VARIABLES & GETTER/SETTER
*/
private GgsnAcceptDTO ggsnAccept;
private GgsnAcceptDTO selectedGgsnAccept;
private List<GgsnAcceptDTO> listGgsnAccept;
public GgsnAcceptDTO getGgsnAccept() {
return ggsnAccept;
}
public void setGgsnAccept(GgsnAcceptDTO ggsnAccept) {
this.ggsnAccept = ggsnAccept;
}
public GgsnAcceptDTO getSelectedGgsnAccept() {
return selectedGgsnAccept;
}
public void setSelectedGgsnAccept(GgsnAcceptDTO selectedGgsnAccept) {
this.selectedGgsnAccept = selectedGgsnAccept;
}
public List<GgsnAcceptDTO> getListGgsnAccept() {
return listGgsnAccept;
}
public void setListGgsnAccept(List<GgsnAcceptDTO> listGgsnAccept) {
this.listGgsnAccept = listGgsnAccept;
}
/**
* SERVICE
*
*/
#Autowired
private GgsnAcceptService ggsnAcceptServ;
/**
* INIT
*
*/
#PostConstruct
#Override
public void init() {
updateCtrl();
}
#Override
public void updateCtrl() {
clear();
System.out.println(ggsnAcceptServ == null);
listGgsnAccept = ggsnAcceptServ.findAll();
}
private String ggsnAcceptSelected;
#Override
public void updateDB() {
try {
if (ggsnAccept == null) {
throw new LogicException("nullSelected", "GGSN Config is not yet selected!");
}
if (formStatus == Const.BTN_ADD && ggsnAcceptServ.isExisted(ggsnAccept)) {
throw new LogicException("insertExisted", "GGSN Config existed!");
}
// if (systemCfgSelected != null && systemCfgSelected.equals(systemCfg.getSystemCfgName()) && langServ.isExisted(systemCfg)) {
// throw new LogicException("updateExisted", "GGSN Config is existed!");
// }
BaseMessage msg = ggsnAcceptServ.updateGgsn(ggsnAccept);
if (msg.isSuccess()) {
reportSuccess("msgInfo", "Success");
}
updateCtrl();
selectedGgsnAccept = (GgsnAcceptDTO) msg.getOutputObject();
} catch (LogicException ex) {
reportError("msgInfo", ex.getDescription());
} catch (Exception ex) {
logger.error(ex, ex);
}
}
#Override
public void deleteDB() {
try {
if (ggsnAccept == null) {
throw new LogicException("nullSelected", "GGSN Config is not selected yet!");
}
BaseMessage msg = ggsnAcceptServ.deleteGgsn(ggsnAccept);
if (msg.isSuccess()) {
reportSuccess("msgInfo", "msg.delete.success");
}
updateCtrl();
} catch (LogicException ex) {
reportError("msgInfo", ex.getDescription());
} catch (Exception ex) {
logger.error(ex, ex);
}
}
#Override
public void prepareAdd() {
ggsnAccept = new GgsnAcceptDTO();
selectedGgsnAccept = null;
}
#Override
public void prepareEdit() {
if (selectedGgsnAccept != null) {
ggsnAccept = selectedGgsnAccept;
}
}
#Override
public void prepareDelete() {
if (selectedGgsnAccept != null) {
ggsnAccept = selectedGgsnAccept;
}
}
#Override
public void clear() {
selectedGgsnAccept = null;
ggsnAccept = null;
}
#Override
public void onRowChangeListener() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
An interface GgsnAcceptService.java:
package com.viettel.pcrf.webconfig.service;
import com.viettel.fw.dto.BaseMessage;
import com.viettel.pcrf.dto.GgsnAcceptDTO;
import java.util.List;
public interface GgsnAcceptService {
public List<GgsnAcceptDTO> findAll();
public List<GgsnAcceptDTO> findAll(List filters);
public BaseMessage updateGgsn(GgsnAcceptDTO ggsn) throws Exception;
public BaseMessage deleteGgsn(GgsnAcceptDTO ggsn) throws Exception;
public boolean isExisted(GgsnAcceptDTO ggsn) throws Exception;
}
And a class implement above interface:
package com.viettel.pcrf.webconfig.service;
import com.viettel.fw.common.util.extjs.FilterRequest;
import com.viettel.fw.dto.BaseMessage;
import com.viettel.pcrf.webconfig.repo.GgsnAcceptRepository;
import com.viettel.pcrf.common.util.mapper.GgsnAcceptMapper;
import com.viettel.pcrf.dto.GgsnAcceptDTO;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.viettel.service.BaseServiceImpl;
import java.util.ArrayList;
#Service
public class GgsnAcceptServiceImpl extends BaseServiceImpl implements GgsnAcceptService {
private GgsnAcceptMapper mapper = new GgsnAcceptMapper();
#Autowired
private GgsnAcceptRepository repository;
public Logger logger = Logger.getLogger(GgsnAcceptService.class);
#Override
public List<GgsnAcceptDTO> findAll(List filters) {
return mapper.toDtoBean(repository.findAll(repository.toPredicate(filters)));
}
#Override
public List<GgsnAcceptDTO> findAll() {
return mapper.toDtoBean(repository.findAll());
}
#Override
public BaseMessage updateGgsn(GgsnAcceptDTO ggsn) throws Exception {
BaseMessage msg = new BaseMessage();
GgsnAcceptDTO newGgsn = mapper.toDtoBean(repository.saveAndFlush(mapper.toPersistenceBean(ggsn)));
msg.setOutputObject(newGgsn);
msg.setSuccess(true);
return msg;
}
#Override
public boolean isExisted(GgsnAcceptDTO ggsn) throws Exception {
List<FilterRequest> listReq = new ArrayList<>();
listReq.add(new FilterRequest("IP", ggsn.getIp()));
return repository.findOne(repository.toPredicate(listReq)) != null;
}
#Override
public BaseMessage deleteGgsn(GgsnAcceptDTO ggsn) throws Exception {
BaseMessage msg = new BaseMessage();
repository.delete(mapper.toPersistenceBean(ggsn));
msg.setSuccess(true);
return msg;
}
}
I got an null error when trying to access a page call controller. Is there anything wrong with my code ?
My property ggsnAcceptServ always null although i have already set autowired for it. I'm new in Spring, please help to explain why this property null. Any help would be great.
You have a problem mixing jsf and spring:
#Component
#ManagedBean(name = "ggsnAcceptController")
#Scope("view")
Your controller will be executed in jsf context not in spring context. Thats why autowiering not working.

How to call a method in another class using robotium

Using Robotium for my Android automation I find myself creating the same steps for each test case.
I always need to "Login" and "Logout", I've been trying to create a FunctionsTestClass so I can simply call rLogin(); and rLogout();
Here is an example:
Adding my complete files.
'package com.myproject.mobile.test;
import android.test.ActivityInstrumentationTestCase2;
import android.app.Activity;
import junit.framework.AssertionFailedError;
import com.bitbar.recorder.extensions.ExtSolo;
import com.jayway.android.robotium.solo.By;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
'public class Logout extends ActivityInstrumentationTestCase2<Activity> {
private static final String LAUNCHER_ACTIVITY_CLASSNAME = "com.myproject.mobile.MainActivity";
private static Class<?> launchActivityClass;
static {
try {
launchActivityClass = Class.forName(LAUNCHER_ACTIVITY_CLASSNAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private static ExtSolo solo; // ExtSolo is an extension of Robotium Solo that helps
// collecting better test execution data during test
// runs
#SuppressWarnings("unchecked")
public Logout() {
super((Class<Activity>) launchActivityClass);
}
#Override
public void setUp() throws Exception {
super.setUp();
solo = new ExtSolo(getInstrumentation(), getActivity(), this.getClass()
.getCanonicalName(), getName());
}
#Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
solo.tearDown();
super.tearDown();
}
public static void logginin() throws Exception {
try {
//enter username
solo.sleep(17000);
throw e;
} catch (Exception e) {
solo.fail(
"com.myproject.mobile.test.MainActivityTest.testRecorded_scr_fail",
e);
throw e;
}
}
}'
Adding my second file
package com.mypackage.mobile.test;
import android.test.ActivityInstrumentationTestCase2;
import android.app.Activity;
import junit.framework.AssertionFailedError;
import com.bitbar.recorder.extensions.ExtSolo;
import com.jayway.android.robotium.solo.By;
import com.mypackage.mobile.test.*;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
'public class Test extends ActivityInstrumentationTestCase2<Activity> {
private static final String LAUNCHER_ACTIVITY_CLASSNAME = "com.mypackage.mobile.MainActivity";
private static Class<?> launchActivityClass;
static {
try {
launchActivityClass = Class.forName(LAUNCHER_ACTIVITY_CLASSNAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private static ExtSolo solo; // ExtSolo is an extension of Robotium Solo that helps
// collecting better test execution data during test
// runs
#SuppressWarnings("unchecked")
public Test() {
super((Class<Activity>) launchActivityClass);
}
#Override
public void setUp() throws Exception {
super.setUp();
solo = new ExtSolo(getInstrumentation(), getActivity(), this.getClass()
.getCanonicalName(), getName());
}
#Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
solo.tearDown();
super.tearDown();
}
public void testRecorded() throws Exception {
try {
Logout.logginin();
} catch (AssertionFailedError e) {
solo.fail(
"com.mypackage.name.MainActivityTest.testRecorded_scr_fail",
e);
throw e;
} catch (Exception e) {
solo.fail(
"com.mypackage.name.MainActivityTest.testRecorded_scr_fail",
e);
throw e;
}
}
}
Updated the bottom two code to reflect my project.
Don't create testcase with name testLoggingin() . Instead of that creat a class having function login(). So that, whenever its needed you can import it and can call the function to login. And you can check conditions using assert.

Categories