Reference to a bean in a constructor of a different class - spring

I am trying to migrate a legacy project into Spring Boot. There is an auto-generated class I've been struggling with. Please see below the original class that provides the interface for a web service.
/**
* This class was generated by the JAX-WS RI. JAX-WS RI 2.2.9-b130926.1035 Generated source version: 2.2
*
*/
#WebServiceClient(name = "SomeWebService", targetNamespace = "http://www.somewebservice.com")
public class SomeWebService extends Service {
private final static URL SomeWebService_WSDL_LOCATION;
private final static WebServiceException SomeWebService_EXCEPTION;
private final static QName SomeWebService_QNAME = new QName("http://www.somewebservice.com", "SomeWebService");
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL(DataAccessLayer.systemProps.getProperty("configurable_service_url"));
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
SomeWebService_WSDL_LOCATION = url;
SomeWebService_EXCEPTION = e;
}
public SomeWebService() {
super(__getWsdlLocation(), SomeWebService_QNAME);
}
public SomeWebService(WebServiceFeature... features) {
super(__getWsdlLocation(), SomeWebService_QNAME, features);
}
public SomeWebService(URL wsdlLocation) {
super(wsdlLocation, SomeWebService_QNAME);
}
public SomeWebService(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, SomeWebService_QNAME, features);
}
public SomeWebService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public SomeWebService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName, features);
}
/**
*
* #return returns SomeWebService
*/
#WebEndpoint(name = "SomeWebServicePort")
public SomeWebService getSomeWebServicePort() {
return super.getPort(new QName("http://www.somewebservice.com", "SomeWebServicePort"), SomeWebService.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in
* the <code>features</code> parameter will have their default values.
* #return returns SomeWebService
*/
#WebEndpoint(name = "SomeWebServicePort")
public SomeWebService getSomeWebServicePort(WebServiceFeature... features) {
return super.getPort(new QName("http://www.somewebservice.com", "SomeWebServicePort"), SomeWebService.class, features);
}
private static URL __getWsdlLocation() {
if (SomeWebService_EXCEPTION != null) {
throw SomeWebService_EXCEPTION;
}
return SomeWebService_WSDL_LOCATION;
}
}
Please note the line:
url = new URL(DataAccessLayer.systemProps.getProperty("configurable_service_url"));
This is how it is configured in the legacy code, in a static block...
The first thing I did is add a config class to pick up properties from a file as follows:
#Configuration
#PropertySource({"classpath:someWebservice.properties"})
public class SomeWebserviceConfiguration {
}
However, I am not able to figure out a way to create a bean (a url), and then use the bean in the constructors.
Can someone give me some ideas or point me in the right direction? Thanks so much!

OK. I have found a solution. The code looks a bit unseemly. But it works.
First I need to add a config class, and make it ApplicationContextAware.
#Configuration
#PropertySource({ "classpath:somewebservice.properties" })
public class WebServiceConfiguration implements ApplicationContextAware {
private static ApplicationContext ctx;
#Value("${configurable_service_url}")
private String serviceUrlProp;
#Bean
#Qualifier("serviceUrl")
public URL getServiceUrl() throws MalformedURLException {
return new URL(serviceUrlProp);
}
#Override
public void setApplicationContext(ApplicationContext appContext) throws BeansException {
ctx = appContext;
}
public static ApplicationContext getApplicationContext() {
return ctx;
}
}
This is where the property "configurable_service_url" gets picked up. We also create a URL bean and make it available in the container. The static ApplicationContext is for the web service class to grab and then it will get hold of the bean.
/**
* This class was generated by the JAX-WS RI. JAX-WS RI 2.2.9-b130926.1035 Generated source version: 2.2
*
*/
#WebServiceClient(name = "SomeWebService", targetNamespace = "http://www.somewebservice.com")
public class SomeWebService extends Service {
private final static QName SomeWebService_QNAME = new QName("http://www.somewebservice.com", "SomeWebService");
public SomeWebService() {
super((URL) BlazeConfiguration.getApplicationContext().getBean("getServiceUrl"), SomeWebService_QNAME);
}
public SomeWebService(WebServiceFeature... features) {
super((URL) BlazeConfiguration.getApplicationContext().getBean("getServiceUrl"), SomeWebService_QNAME, features);
}
public SomeWebService(URL wsdlLocation) {
super(wsdlLocation, SomeWebService_QNAME);
}
public SomeWebService(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, SomeWebService_QNAME, features);
}
public SomeWebService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public SomeWebService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName, features);
}
/**
*
* #return returns SomeWebService
*/
#WebEndpoint(name = "SomeWebServicePort")
public SomeWebService getSomeWebServicePort() {
return super.getPort(new QName("http://www.somewebservice.com", "SomeWebServicePort"), SomeWebService.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in
* the <code>features</code> parameter will have their default values.
* #return returns SomeWebService
*/
#WebEndpoint(name = "SomeWebServicePort")
public SomeWebService getSomeWebServicePort(WebServiceFeature... features) {
return super.getPort(new QName("http://www.somewebservice.com", "SomeWebServicePort"), SomeWebService.class, features);
}
}
In the constructor
public SomeWebService() {
super((URL) BlazeConfiguration.getApplicationContext().getBean("getServiceUrl"), SomeWebService_QNAME);
}
I first tried to use the name "serviceUrl". But it complained that it could not find it in the application context. I had to print out all the available beans in the container to see that I needed to use "getServiceUrl", which is the method name, to retrieve the bean.

Related

Springboot Mongo db methods doesnt rollback transactions

Hi i am using 2 mongo template in my codebase
and my code saves data in mongo db using both mongo template and Spring repository class.save() .In methods which has #Transactional doesnt rollback DB changes even if some error occurs in code execution.
Below is the snippet of my mongoconfig configurations
#Configuration
#EnableMongoAuditing
#EnableMongoRepositories
public class MongoConfig extends AbstractMongoClientConfiguration {
#Value("${common.db.name}")
private String dbName;
#Value("${SPRING_DATA_MONGODB_URI}")
private String dbUrl;
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
#Override
protected String getDatabaseName() {
return dbName;
}
/**
* Below bean is created as we want to make our code transactional.
* #param dbFactory
* #return
*/
#Bean(name="primaryTransactionManager")
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
transactionManager.setRollbackOnCommitFailure(true);
return transactionManager;
}
#Override
public MongoClient mongoClient() {
ConnectionString connectionString = new ConnectionString(dbUrl);
MongoClientSettings mongoClientSettings = MongoClientSettings.builder().applyConnectionString(connectionString).build();
return MongoClients.create(mongoClientSettings);
}
#Bean(name="primaryMongoTemplate")
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoClient(), getDbName());
}
}
#Configuration
#EnableMongoRepositories
public class SecondaryMongoConfig {
#Value("${common.secondary.db.name}")
private String dbName;
#Value("${COMMON_SECONDARY_SPRING_DATA_MONGODB_URI}")
private String mongoDBURI;
public String getMongoDBURI() {
return mongoDBURI;
}
public void setMongoDBURI(String mongoDBURI) {
this.mongoDBURI = mongoDBURI;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
/**
* Below bean is created as we want to make our code transactional.
* #param dbFactory
* #return
*/
#Bean(name="secondaryTransactionManager")
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
transactionManager.setRollbackOnCommitFailure(true);
return new MongoTransactionManager(dbFactory);
}
#Bean(name="secondaryMongoClient")
public MongoClient secondaryMongoClient() {
ConnectionString connectionString = new ConnectionString(getMongoDBURI());
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(mongoClientSettings);
}
#Bean(name="secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate() {
return new MongoTemplate(secondaryMongoClient(), getDbName());
}
}
Below is my sample code snippet of method annoted with #Transactional
#Override
#Transactional(transactionManager = "primaryTransactionManager",rollbackFor = {Exception.class})
public String addNewRecipe() throws Exception{
RecipesDAO recipesDao = new RecipesDAO();
recipesDao.setResourceId(UUID.randomUUID().toString());
recipeRepository.save(recipesDao);
throw new Exception();
// return "dummy";
}
I got solution after checking each and every method of classes used in my class MongoConfig.java.Below is the snippet of code which i had to use in order to rollback transactions when exceptions occured in code execution flow
#Bean(name="primaryMongoTemplate")
public MongoTemplate mongoTemplate() {
MongoTemplate primaryMongoTemplate = new MongoTemplate(mongoClient(), getDbName());
primaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
return primaryMongoTemplate;
}
#Bean(name="secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate() {
MongoTemplate secondaryMongoTemplate = new MongoTemplate(secondaryMongoClient(), getDbName());
secondaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
return secondaryMongoTemplate;
}
Earlier wherever code of creating new or modifying mongodb docs was there like say somerepository.save(s) code used to create or modify documents immedialtely but by adding primaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS); and secondaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
code waits for complete execution flow and checks if any exception occured in this execution flow.It creates or modifies documents only after checking no exception occured in execution flow.

MongoDB -Consider defining a bean of type 'org.springframework.data.mongodb.repository.query.MongoEntityInformation' in your configuration

My Student entity class
package com.example.entity;
import java.io.Serializable;
import javax.persistence.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "student")
public class StudentMongo implements Serializable {
private static final long serialVersionUID = 8764013757545132519L;
#Id
private Long id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
My Repository
package com.example.repository;
import javax.annotation.Resource;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
import org.springframework.stereotype.Repository;
import com.example.entity.StudentMongo;
#Repository
public class StudentMongoRepository extends SimpleMongoRepository<StudentMongo, Long> {
#Resource
MongoOperations mongoOperations;
public StudentMongoRepository(MongoEntityInformation<StudentMongo, Long> metadata, MongoOperations mongoOperations) {
super(metadata, mongoOperations);
}
}
My configuration class
#Configuration
#EnableMongoRepositories(basePackageClasses = {com.example.repository.StudentMongoRepository.class})
public class MongoConfiguration {
}
Spring boot application
When i try to start the application i am getting following application
2017-11-20 09:04:48.937 ERROR 23220 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.repository.StudentMongoRepository required a bean of type 'org.springframework.data.mongodb.repository.query.MongoEntityInformation' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.data.mongodb.repository.query.MongoEntityInformation' in your configuration.
Consider defining a bean of type 'org.springframework.data.mongodb.repository.query.MongoEntityInformation' in your configuration
How to create EntityInformation bean as said by spring framework
Getting above issue while running my application . how to pass entity information
suggest me how to use SimpleMongorepository
I had the same problem and I solved externalizating the MongoEntityInformationSupport of Spring Data.
Do this:
Create theese three classes:
public final class MongoEntityInformationSupport {
private MongoEntityInformationSupport() {}
/**
* Factory method for creating {#link MongoEntityInformation}.
*
* #param entity must not be {#literal null}.
* #param idType can be {#literal null}.
* #return never {#literal null}.
*/
#SuppressWarnings("unchecked")
public static <T, ID> MongoEntityInformation<T, ID> entityInformationFor(MongoPersistentEntity<?> entity,
#Nullable Class<?> idType) {
Assert.notNull(entity, "Entity must not be null!");
MappingMongoEntityInformation<T, ID> entityInformation = new MappingMongoEntityInformation<T, ID>(
(MongoPersistentEntity<T>) entity, (Class<ID>) idType);
return ClassUtils.isAssignable(Persistable.class, entity.getType())
? new PersistableMongoEntityInformation<T, ID>(entityInformation) : entityInformation;
}
}
Ps.: Put PersistableMongoEntityInformation in the same package of MongoEntityInformationSupport
#RequiredArgsConstructor //<-- Lombok
class PersistableMongoEntityInformation<T, ID> implements MongoEntityInformation<T, ID> {
private final #NonNull
MongoEntityInformation<T, ID> delegate;
/*
* (non-Javadoc)
* #see org.springframework.data.mongodb.repository.MongoEntityInformation#getCollectionName()
*/
#Override
public String getCollectionName() {
return delegate.getCollectionName();
}
/*
* (non-Javadoc)
* #see org.springframework.data.mongodb.repository.MongoEntityInformation#getIdAttribute()
*/
#Override
public String getIdAttribute() {
return delegate.getIdAttribute();
}
/*
* (non-Javadoc)
* #see org.springframework.data.repository.core.EntityInformation#isNew(java.lang.Object)
*/
#Override
#SuppressWarnings("unchecked")
public boolean isNew(T t) {
if (t instanceof Persistable) {
return ((Persistable<ID>) t).isNew();
}
return delegate.isNew(t);
}
/*
* (non-Javadoc)
* #see org.springframework.data.repository.core.EntityInformation#getId(java.lang.Object)
*/
#Override
#SuppressWarnings("unchecked")
public ID getId(T t) {
if (t instanceof Persistable) {
return ((Persistable<ID>) t).getId();
}
return delegate.getId(t);
}
/*
* (non-Javadoc)
* #see org.springframework.data.repository.core.support.PersistentEntityInformation#getIdType()
*/
#Override
public Class<ID> getIdType() {
return delegate.getIdType();
}
/*
* (non-Javadoc)
* #see org.springframework.data.repository.core.support.EntityMetadata#getJavaType()
*/
#Override
public Class<T> getJavaType() {
return delegate.getJavaType();
}
}
I created this MongoHelper just for simplify
public class MongoHelper {
public static MongoEntityInformation getEntityInformationFor(Class clazz, Class idClazz) {
TypeInformation typeInformation = ClassTypeInformation.from(clazz);
MongoPersistentEntity mongoPersistentEntity = new BasicMongoPersistentEntity(typeInformation);
return MongoEntityInformationSupport.entityInformationFor(mongoPersistentEntity, idClazz);
}
}
Finally
You can use like this(Sample with QuerydslMongoPredicateExecutor):
public class TicketRepositoryCustomImpl extends QuerydslMongoPredicateExecutor<Ticket> implements TicketRepositoryCustom {
//The MongoOperations will be autowired
public TicketRepositoryCustomImpl(MongoOperations mongoOperations) {
super(MongoHelper.getEntityInformationFor(Ticket.class, String.class), mongoOperations);
}
#Override
public Optional<Ticket> findWithFilter(TicketFilter filter) {
BooleanBuilder builder = new BooleanBuilder();
//populate the builder
return findOne(builder.getValue());
}
}
First of all I would like to say that please DON'T USE IMPLEMENTATION CLASS INSTEAD USE AN INTERFACE.
declare an Interface and extend it from MongoRepository<T,ID>, spring will provide the implementation out-of-the-box.
#Repository
public interface StudentMongoRepository extends MongoRepository<T,ID>{
#Autowired
private MongoOperations mongoOperations;
This should work.
Try this :-
don't make it autowired just make a variable like this .
private MongoTemplate mongoTemplate;
XXService extends PagingAndSortingRepository<XX, String>{
}
----------------------------------------------------------------
#Service
public class XXXmpl extends SimpleMongoRepository<XX, String> implements XXService {
public XXImpl(MongoOperations mongoOperations) {
super(new MongoRepositoryFactory(mongoOperations).getEntityInformation(XXX.class), mongoOperations);
}
}

Spring, AspectJ: injection for deserialized objects

I need to put some object into ActiveMQ and then deserialize it. This object contain transient field which should be initialized upon deserialization. According to this doc (http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-atconfigurable) it should work automatically in the Spring, but it doesn't. CloudBean is always null after the deserialization.
Here are my classes:
package core.utilities.handlers;
//imports...
#Component
#Configurable
public class InitialCopyHandler implements JobHandler {
private static final long serialVersionUID = 2617677940515776720L;
private static Logger logger = Logger.getLogger(InitialCopyHandler.class);
private String username;
private String password;
#Autowired private transient CloudBean cloudBean;
public InitialCopyHandler() {
}
public InitialCopyHandler( String username, String password ) {
this.username = username;
this.password = password;
}
#Override
public void handle() {
try {
logger.info("Copy from default to " + username);
String webCloudDataDir = cloudBean.getWebCloudDataDir();
Sardine defaultSardine = cloudBean.getDefaultSardine();
InputStream is = defaultSardine.get(webCloudDataDir + FILE_COUNTRIES_LIST);
cloudBean.getUserSardine(username,password).put(webCloudDataDir + FILE_COUNTRIES_LIST, is);
} catch (IOException e) {
e.printStackTrace();
}
}
}
CloudBean.java:
package core.domain.cloud;
//imports...
#Component
public class CloudBean {
protected Sardine defaultSardine;
protected Sardine userSardine;
protected String webCloudDataDir;
protected String webCloud;
protected static String defaultCar;
protected static String defaultCarPassword;
protected HttpHeaders headers;
#Autowired private ConfigurationFactory configuration;
public CloudBean() {
}
// init block
#PostConstruct
private void init() {
webCloudDataDir = configuration.getConfigurationValue(DEFAULT_CLOUD_WEBDAV_LOCATION) + DIR_CLOUD_DATA;
webCloud = configuration.getConfigurationValue(DEFAULT_CLOUD_LOCATION);
defaultCar = configuration.getConfigurationValue(DEFAULT_CLOUD_ACCOUNT);
defaultCarPassword = configuration.getConfigurationValue(DEFAULT_CLOUD_ACCOUNT_PASSWORD);
defaultSardine = SardineFactory.begin(defaultCar, defaultCarPassword);
defaultSardine.enableCompression();
headers = HttpUtilities.initHeaders(defaultCar,defaultCarPassword);
}
/**
* Initializes Sardine for the particular user
* #param username
* #param password
* #return Sardine
*/
public Sardine getUserSardine( String username, String password ) {
userSardine = SardineFactory.begin(username,password);
userSardine.enableCompression();
return userSardine;
}
public Sardine getDefaultSardine() {
return defaultSardine;
}
public String getWebCloudDataDir() {
return webCloudDataDir;
}
}
Excerpt from the Consumer.java (deserialization part):
#Override
public void onMessage(Message message) {
if( message instanceof ObjectMessage ) {
ObjectMessage objectMessage = (ObjectMessage)message;
try {
JobHandler msg = (JobHandler)objectMessage.getObject();
es.execute(new Runnable() {
#Override
public void run() {
msg.handle();
}
});
} catch (JMSException e) {
e.printStackTrace();
}
}
}
What is wrong?
In your code Spring is just not involved in the deserialization, so it cannot inject any dependencies.
In the linked spring documentation the pojos are created by a spring factory. You cannot use that approach because you create your instances by deserialization.
What you can do :
In your Consumer class get a bean factory injected :
#Autowired
AutowireCapableBeanFactory beanFactory;
after deserializing the object autowire it :
JobHandler msg = (JobHandler)objectMessage.getObject();
beanFactory.autowireBean(msg);
thats all.

Spring4 session

Excuse me ! I have a question here. Which version of Spring is “org.springframework.session.*” ? I can't find it in Spring4.0 jar at all.
here is the class:
public abstract class AbstractSessionWebSocketMessageBrokerConfigurer<S extends ExpiringSession>
extends AbstractWebSocketMessageBrokerConfigurer {
#Autowired
#SuppressWarnings("rawtypes")
private SessionRepository sessionRepository;
#Autowired
private ApplicationEventPublisher eventPublisher;
#Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(sessionRepositoryInterceptor());
}
#Override
public final void registerStompEndpoints(StompEndpointRegistry registry) {
configureStompEndpoints(new SessionStompEndpointRegistry(registry,sessionRepositoryInterceptor()));
}
/**
* Register STOMP endpoints mapping each to a specific URL and (optionally)
* enabling and configuring SockJS fallback options with a
* {#link SessionRepositoryMessageInterceptor} automatically added as an
* interceptor.
*
* #param registry
* the {#link StompEndpointRegistry} which automatically has a
* {#link SessionRepositoryMessageInterceptor} added to it.
*/
protected abstract void configureStompEndpoints(StompEndpointRegistry registry);
#Override
public void configureWebSocketTransport(
WebSocketTransportRegistration registration) {
registration.addDecoratorFactory(wsConnectHandlerDecoratorFactory());
}
#Bean
public WebSocketRegistryListener webSocketRegistryListener() {
return new WebSocketRegistryListener();
}
#Bean
public WebSocketConnectHandlerDecoratorFactory wsConnectHandlerDecoratorFactory() {
return new WebSocketConnectHandlerDecoratorFactory(eventPublisher);
}
#Bean
#SuppressWarnings("unchecked")
public SessionRepositoryMessageInterceptor<S> sessionRepositoryInterceptor() {
return new SessionRepositoryMessageInterceptor<S>(sessionRepository);
}
static class SessionStompEndpointRegistry implements StompEndpointRegistry {
private final StompEndpointRegistry registry;
private final HandshakeInterceptor interceptor;
public SessionStompEndpointRegistry(StompEndpointRegistry registry,HandshakeInterceptor interceptor) {
this.registry = registry;
this.interceptor = interceptor;
}
public StompWebSocketEndpointRegistration addEndpoint(String... paths) {
StompWebSocketEndpointRegistration endpoints = registry.addEndpoint(paths);
endpoints.addInterceptors(interceptor);
return endpoints;
}
}
}
Spring Session is a separate project: https://github.com/spring-projects/spring-session.
You should use some dependency management tool (Gradle or Maven) to have a control over artifacts for your application.
See WebScoket sample there: https://github.com/spring-projects/spring-session/tree/master/samples/websocket .
A Spring Session artifact is:
compile "org.springframework.session:spring-session:1.0.0.RC1"

spring injection java.lang.NullPointerException

when I have injected the been AdminService the java.lang.NullPointerException appeared , although I inject this bean with the same way in another managed bean and everything works :
#ManagedBean
#SessionScoped
public class ScheduleController implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1489523494215832724L;
private ScheduleModel eventModel;
#ManagedProperty(value = "#{adminService}")
AdminService adminService;
private ScheduleEvent event = new DefaultScheduleEvent();
public ScheduleController() {
List<Service> = adminService.getAllService();
}
public AdminService getAdminService() {
return adminService;
}
public void setAdminService(AdminService adminService) {
this.adminService = adminService;
}
AdminService implementation:
Service("adminService")
public class AdminServiceImpl implements AdminService,Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Autowired
AdminDao adminDao ;
// adminDao injected by spring
#Transactional
public void add(Admin admin) {
adminDao.save(admin);
}
#Transactional
public void edit(Admin admin) {
adminDao.update(admin);
}
#Transactional
public void delete(Admin admin) {
adminDao.delete(admin);
}
#Transactional
public Admin getAdmin(Integer adminId) {
return adminDao.findById(adminId);
}
#Transactional
public List<Admin> getAllAdmin() {
return adminDao.findAll();
}
/**
* #return the adminDao
*/
public AdminDao getAdminDao() {
return adminDao;
}
/**
* #param adminDao the adminDao to set
*/
public void setAdminDao(AdminDao adminDao) {
this.adminDao = adminDao;
}
#Override
public Admin authenticate(String adminName, String adminPass) {
return this.adminDao.authenticate(adminName, adminPass);
}
}
You're trying to access the injected dependency during construction of the bean. This is obviously not going to work. You're basically expecting that it all works like follows under the covers:
ScheduleController scheduleController; // Declare.
scheduleController.adminService = new AdminService(); // Inject.
scheduleController = new ScheduleController(); // Construct.
This makes no sense. It's not possible to set an instance variable before the instance is constructed. Instead, it works like follows:
ScheduleController scheduleController; // Declare.
scheduleController = new ScheduleController(); // Construct.
scheduleController.adminService = new AdminService(); // Inject.
If you'd like to perform an action directly after construction and injection, then you should be using a #PostConstruct annotated method.
So, replace
public ScheduleController() {
List<Service> services = adminService.getAllService();
}
by
#PostConstruct
public void init() { // Note: method name is fully free to your choice.
List<Service> services = adminService.getAllService();
}
No need for the <f:event> mess. It also doesn't necessarily need to go in <f:metadata> by the way.
i find the solution , the problem is not a problem of injection is a problem of call, I worked with this ways, and it works :
in the managed bean i add a init method :
public void init(){
List<Service> = adminService.getAllService();
}
and in the page.xhtml :
<f:metadata>
<f:event type="preRenderView" listener="#{scheduleController.init()}"/>
</f:metadata>

Resources