Mongo Template querying the wrong collection - spring

I have a mongodb springboot application that is connected to 2 different databases, that have the same collection names and database names but different uris.
Here is my application.properties
spring.data.mongodb.uri = uri
spring.data.mongodb.secondDB.uri = uri
spring.data.mongodb.database = database_name
spring.data.mongodb.secondDB.database = database_name
My AppConfiguration file
#Configuration
public class MultipleMongoConfig {
#Primary
#Bean(name = "newdb1Properties")
#ConfigurationProperties(prefix = "spring.data.mongodb")
public MongoProperties getNewDb1Props() throws Exception {
return new MongoProperties();
}
#Bean(name = "newdb2Properties")
#ConfigurationProperties(prefix = "spring.data.mongodb.secondDB")
public MongoProperties getNewDb2Props() throws Exception {
return new MongoProperties();
}
#Primary
#Bean(name = "newdb1MongoTemplate")
public MongoTemplate newdb1MongoTemplate() throws Exception {
return new MongoTemplate(newdb1MongoDatabaseFactory(getNewDb1Props()));
}
#Bean(name ="newdb2MongoTemplate")
public MongoTemplate newdb2MongoTemplate() throws Exception {
return new MongoTemplate(newdb2MongoDatabaseFactory(getNewDb2Props()));
}
#Primary
#Bean
public MongoDatabaseFactory newdb1MongoDatabaseFactory(MongoProperties mongo) throws Exception {
return new SimpleMongoClientDatabaseFactory(
mongo.getUri()
);
}
#Bean
public MongoDatabaseFactory newdb2MongoDatabaseFactory(MongoProperties mongo) throws Exception {
return new SimpleMongoClientDatabaseFactory(
mongo.getUri()
);
}
Then I set up config files for each data source
#Configuration
#EnableMongoRepositories(basePackages = {"com.example.app.firstDatabse.Repository"},
mongoTemplateRef = "newdb1MongoTemplate"
)
public class NewDb1Config {
}
and
#Configuration
#EnableMongoRepositories(basePackages = {"com.example.app.secondDatabse.Repository"},
mongoTemplateRef = "newdb2MongoTemplate"
)
public class NewDb1Config {
}
For Model I have the following
#AllArgsConstructor
#NoArgsConstructor
#ToSting
#Document(collection = "coll")
public class FirstModel{
#Id
public String id;
#Field("f_name")
public String firstName;
#Field("l_name")
public String lastName;
#Field("age")
public int age;
#Field("gender")
public String gender;
}
and my second Model is the same
#AllArgsConstructor
#NoArgsConstructor
#ToSting
#Document(collection = "coll")
public class SecondModel{
#Id
public String id;
#Field("f_name")
public String firstName;
#Field("l_name")
public String lastName;
#Field("age")
public int age;
#Field("gender")
public String gender;
}
My controller
#ResController
#RequestMapping("/controller")
public class Controller{
#Autowired
private FirstDataabseRepository repo;
#Autowired
private SecondDataabseRepository repo;
#Resource
private MongoTemplate mongoTemplate;
#RequestMapping("/findByName")
public List<SecondModel> findByName(){
Criteria criteria = new Criteria();
criteria = Criteria.where("f_name").is("John");
Query q = new Query(criteria);
List<SecondModel> results = mongoTemplate.find(q,SecondModel.class);
return results;
}
}
So the results show the results of the first collection not the second one. What do I need to do for mongoTemplate to query the second collection not the first one.

Solution
I have to add a qualifier and have a mongoTemplate for each collection
#ResController
#RequestMapping("/controller")
public class Controller{
#Autowired
private FirstDataabseRepository repo;
#Autowired
private SecondDataabseRepository repo;
#Resource
#Qualifier(value="newdb1MongoTemplate")
private MongoTemplate mongoTemplate;
#Resource
#Qualifier(value="newdb2MongoTemplate")
private MongoTemplate mTemplate;
#RequestMapping("/findByName")
public List<SecondModel> findByName(){
Criteria criteria = new Criteria();
criteria = Criteria.where("f_name").is("John");
Query q = new Query(criteria);
List<SecondModel> results = mTemplate.find(q,SecondModel.class);
return results;
}
}

Related

'Couldn't find PersistentEntity for type class' exception in Spring boot MongoRepository

In here I have configured two databases in mongodb. As described in this tutorial (link). So basically I override the MongoDataAutoConfiguration and MongoProperties implementations.
The property yml file :
spring:
autoconfigure:
exclude:
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration
mongodb:
primary:
host: 127.0.0.1
port: 27017
database: db_admin_crm
secondary:
host: 127.0.0.1
port: 27017
database: lead_forms
MultipleMongoProperties class :
#Data
#ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {
private MongoProperties primary = new MongoProperties();
private MongoProperties secondary = new MongoProperties();
//getters and setters
}
MultipleMongoConfig class :
#Configuration
#RequiredArgsConstructor
#EnableConfigurationProperties(MultipleMongoProperties.class)
public class MultipleMongoConfig {
#Autowired
private final MultipleMongoProperties mongoProperties;
public MultipleMongoConfig() {
mongoProperties = null;
}
#Primary
#Bean(name = "primaryMongoTemplate")
public MongoTemplate primaryMongoTemplate() throws Exception {
return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
}
#Bean(name = "secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate() throws Exception {
return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
}
#Bean
#Primary
public MongoDbFactory primaryFactory(final MongoProperties mongo) throws Exception {
return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
mongo.getDatabase());
}
#Bean
public MongoDbFactory secondaryFactory(final MongoProperties mongo) throws Exception {
return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
mongo.getDatabase());
}
}
PrimaryMongoConfig :
#Configuration
#EnableMongoRepositories(basePackages = "io.crm.service.repositories",
mongoTemplateRef = "primaryMongoTemplate")
public class PrimaryMongoConfig{
}
SecondaryMongoConfig :
#Configuration
#EnableMongoRepositories(basePackages = "io.crm.service.repositories.report.repositories",
mongoTemplateRef = "secondaryMongoTemplate")
public class SecondaryMongoConfig {
}
The Repository class :
#RepositoryRestResource(collectionResourceRel = "users",path = "users",excerptProjection = UserProjection.class)
public interface UserRepository extends MongoRepository<User, String> {
}
User model class :
#Id
private String id;
private String email;
private String name;
private String businessName;
private String phone;
private String address;
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private Date createdTime;
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private Date updatedTime;
#Field("bookletSignUps")
#DBRef
private List<BookletSignUp> bookletSignUps;
#Field("eventSignUps")
#DBRef
private List<EventSignUp> eventSignUps;
#Field("infoSignUps")
#DBRef
private List<InfoSignUp> infoSignUps;
#Field("webinarSignUps")
#DBRef
private List<WebinarSignUp> webinarSignUps;
The projection :
#Projection(name = "userExcerpt", types = User.class)
public interface UserProjection {
String getId();
String getName();
String getEmail();
String getBusinessName();
String getPhone();
String getAddress();
Date getCreatedTime();
Date getUpdatedTime();
List<BookletSignUp> getBookletSignUps();
List<EventSignUp> getEventSignUps();
List<InfoSignUp> getInfoSignUps();
List<WebinarSignUp> getWebinarSignUps();
}
But when im trying to do a GET request to the REST endpoint http://localhost:9090/users/ im getting java.lang.IllegalArgumentException: Couldn't find PersistentEntity for type class io.crm.service.models.User! exception here. What could be gone wrong here? Ideas will be very much appreciated. Thanks in advance.

I can not inject Map<String, String> from YAML file

I have this properties in my YAML file:
request-topic:
topics:
IMPORT_CHARGES: topic-name-1
IMPORT_PAYMENTS: topic-name-2
IMPORT_CATALOGS: topic-name-3
And this class:
#Getter
#Setter
#Component
#ConfigurationProperties(prefix = "topic-properties")
public class TopicProperties {
private Map<String, String> topics = new HashMap<>();
public String getTopicNameByType(String type){
return topics.get(type);
}
}
But when I autowire this properies I get empty Map:
#Service
public class TopicRouterImpl implements TopicRouter {
private final TopicProperties topics;
public TopicRouterImpl(TopicProperties topics) {
this.topics = topics;
}
#PostConstruct
public void init(){
topics.getTopicNameByType("IMPORT_CHARGES");
}
#Override
public String getTopicName(MessageType messageType) {
return topics.getTopicNameByType(messageType.name());
}
}
This is due to the name mismatch in your yaml file it should be equals to the specified prefix : topic-properties. Like this :
topic-properties:
topics:
IMPORT_CHARGES: topic-name-1
IMPORT_PAYMENTS: topic-name-2
IMPORT_CATALOGS: topic-name-3

Tables not created in Cassandra db using springboot

I tried to create tables in cassandra db on start-up of spring boot application but it doesn't seem to be able to create tables. Below is my configuration. I have the #EnableCassandraRepositories in my Application class. I already created my keyspace by default. So its just the tables that I'm looking to create.
Configuration
#Configuration
public class CassandraConfig extends AbstractCassandraConfiguration {
#Value("${cassandra.contactpoints}")
private String contactPoints;
#Value("${cassandra.port}")
private int port;
#Value("${cassandra.keyspace}")
private String keySpace;
#Value("${cassandra.basePackages}")
private String basePackages;
#Autowired
private Environment environment;
#Override
protected String getKeyspaceName() {
return keySpace;
}
#Override
#Bean
public CassandraClusterFactoryBean cluster() {
final CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
cluster.setContactPoints(contactPoints);
cluster.setPort(port);
return cluster;
}
#Override
#Bean
public CassandraMappingContext cassandraMapping() throws ClassNotFoundException {
return new BasicCassandraMappingContext();
}
}
Entity
#Table
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class AssessmentAttemptDetailsEntity implements Serializable {
#PrimaryKeyColumn(type = PrimaryKeyType.PARTITIONED)
private String assessmentId;
#PrimaryKeyColumn(type = PrimaryKeyType.CLUSTERED)
private String attempid;
}
Application
#SpringBootApplication
#ComponentScan(basePackages = {"com.lte.assessmentanalytics.service","com.lte.assessmentanalytics.config", "com.lte.assessmentanalytics.model", "com.lte.assessmentanalytics.listener"})
#EnableCassandraRepositories("com.lte.assessmentanalytics.model")
public class AssessmentanalyticsApplication {
#Autowired
private AssessmentAttemptRepository assessmentAttemptRepository;
public static void main(String[] args) {
SpringApplication.run(AssessmentanalyticsApplication.class, args);
}
}
Repository
#Repository
public interface AssessmentAttemptRepository extends CassandraRepository<AssessmentAttemptDetailsEntity, Long> {
}
I was able to fix this by modifying my CassandraConfig class to.
#Configuration
#EnableCassandraRepositories("com.lte.assessmentanalytics.model")
public class CassandraConfig extends AbstractCassandraConfiguration {
#Value("${cassandra.contactpoints}")
private String contactPoints;
#Value("${cassandra.port}")
private int port;
#Value("${cassandra.keyspace}")
private String keySpace;
#Value("${cassandra.basePackages}")
private String basePackages;
#Override
protected String getKeyspaceName() {
return keySpace;
}
#Override
protected String getContactPoints() {
return contactPoints;
}
#Override
protected int getPort() {
return port;
}
#Override
public SchemaAction getSchemaAction() {
return SchemaAction.CREATE_IF_NOT_EXISTS;
}
#Override
public String[] getEntityBasePackages() {
return new String[] {basePackages};
}
}

JPA #EntityListener does not work as expected

I am integrating Spring4 and Hibernate5, but there is a problem that I can't resolve.
I use #EntityListener annotation on the BaseEntity class that is a super class for other business model.
Also I use #MappedSuperclass on the BaseEntity.
But it don't work!
Use Spring base annotation and run application successfully.
Also I inserted a record to db.
So I think my configuration of project is current.
Any body let me know why?
Thanks very much.
This is BaseEntity class.
#MappedSuperclass
#EntityListeners(EntityListener.class)
public class BaseEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false, updatable = false)
private Date createDate;
#Column(nullable = false)
private Date modifyDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
This is EntityListener class.
public class EntityListener {
#PrePersist
public void prePersist(BaseEntity entity) {
entity.setCreateDate(new Date());
entity.setModifyDate(new Date());
}
#PreUpdate
public void preUpdate(BaseEntity entity) {
entity.setModifyDate(new Date());
}
}
The following is my project configuration base on Spring annotation.
#Configuration
#EnableWebMvc
//#ImportResource({ "classpath:xxxxx.xml" })
#PropertySources({
#PropertySource("classpath:application.properties")
})
#ComponentScan({"com.yeager.admin.persistence","com.yeager.admin.web","com.yeager.admin.service","com.yeager.admin.common"})
#EnableAspectJAutoProxy
//#EnableRetry
public class AppConfig {
#Bean(name = "multipartResolver")
public CommonsMultipartResolver getResolver() throws IOException {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
return resolver;
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
public static SpringContext springContext() {
return new SpringContext();
}
}
The main configuration about DAL like this,
#Configuration
#EnableTransactionManagement
#PropertySource({"classpath:persistence-mysql.properties"})
public class PersistenceConfig {
#Autowired
private Environment env;
public PersistenceConfig() {
super();
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.yeager.admin.persistence.entity");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
try {
comboPooledDataSource.setDriverClass(env.getProperty("jdbc.driver"));
} catch (PropertyVetoException e) {
e.printStackTrace();
}
comboPooledDataSource.setJdbcUrl(env.getProperty("jdbc.url"));
comboPooledDataSource.setUser(env.getProperty("jdbc.username"));
comboPooledDataSource.setPassword(env.getProperty("jdbc.password"));
comboPooledDataSource.setInitialPoolSize(Integer.valueOf(env.getProperty("datasource.pool.initialPoolSize")));
return comboPooledDataSource;
}
#Bean
public PlatformTransactionManager transactionManager() {
final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private final Properties hibernateProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
hibernateProperties.setProperty("hibernate.generate_statistics",env.getProperty("hibernate.generate_statistics"));
hibernateProperties.setProperty("hibernate.jdbc.fetch_size", env.getProperty("hibernate.jdbc.fetch_size"));
hibernateProperties.setProperty("hibernate.jdbc.batch_size", env.getProperty("hibernate.jdbc.batch_size"));
hibernateProperties.setProperty("hibernate.max_fetch_depth", env.getProperty("hibernate.max_fetch_depth"));
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache",env.getProperty("hibernate.cache.use_second_level_cache"));
hibernateProperties.setProperty("hibernate.cache.use_query_cache",env.getProperty("hibernate.cache.use_query_cache"));
// hibernateProperties.setProperty("hibernate.cache.provider_class",env.getProperty("hibernate.cache.provider_class"));
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");
return hibernateProperties;
}
}
I use LocalSessionFactoryBean class of Hibernate rather than EntityManager class of JPA. I wonder if this cause ?
--------------- 6.19 --------------
I am wrong. I don't should use #EntityListener annotation base on Spring LocalSessionFactoryBean class.
For hibernate5, there is a special configuration way.
http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#annotations-jpa-entitylisteners
Now, I modify my code as following,
#Component
public class EntityEventListener {
#Autowired
private SessionFactory sessionFactory;
#PostConstruct
public void registerListeners(){
EventListenerRegistry eventListenerRegistry = ((SessionFactoryImplementor) sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class);
eventListenerRegistry.prependListeners(EventType.PRE_INSERT, PreInsertEntityListener.class);
}
}
PreInsertEntityListener
public class PreInsertEntityListener implements PreInsertEventListener {
#Override
public boolean onPreInsert(PreInsertEvent event) {
// if (event.getEntity() instanceof AdminUser){
// ((AdminUser) event.getEntity()).setCreateDate(new Date());
// ((AdminUser) event.getEntity()).setModifyDate(new Date());
// }
BaseEntity baseEntity = (BaseEntity) event.getEntity();
baseEntity.setCreateDate(new Date());
baseEntity.setModifyDate(new Date());
return false;
}
}
But, I have a other problem.
I read hibernate doc and search many information about this. My code don't work already when I insert entity data.
Please help me, thanks!
Although you did neither post the concrete / derived entity nor the business code to persist it, the code you posted seems correct.
For giving it a small test I added a generated UID to the super class and created a concrete entity:
import javax.persistence.Entity;
#Entity
public class DerivedEntity extends BaseEntity {
private static final long serialVersionUID = -6441043639437893962L;
}
And since you mentioned Spring, here is a Spring Data JPA repository to save it:
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface DerivedEntityRepository extends CrudRepository<DerivedEntity, Long> {
}
This small test should show that the (#PrePersist) listener works:
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
#RunWith(SpringRunner.class)
#Transactional
#SpringBootTest
public class DerivedEntityRepositoryTests {
#Autowired
private DerivedEntityRepository derivedEntityRepository;
#Test
public void insertDerivedEntity() {
DerivedEntity entity = new DerivedEntity();
entity = derivedEntityRepository.save(entity);
assertThat(entity.getCreateDate()).isNotNull();
}
}
And just to mention it, if you don't want to enhance your custom listener in future, the existing Spring Data JPA AuditingEntityListener does exactly what you are doing at the moment (and even more). In this case you could just enhance a #Configuration class with #EnableJpaAuditing and modify your BaseEntity as following:
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public class BaseEntity implements Serializable {
// ...
#CreatedDate
#Column(nullable = false, updatable = false)
private Date createDate;
#LastModifiedDate
#Column(nullable = false)
private Date modifyDate;
// ...
}
That would make your custom EntityListener dispensable.
Just take a look Spring JPA Auditing for more information. If you want to enhance auditing with Hibernate, try Hibernate Envers.
I ran into this same issue and in my case the listener defined with #EntityListeners was referring to class (not in the same classloader) in another package and it wasn't being scanned. After adding the class to my persistence context it began working as expected.
So always be sure that any classes related to the persistence are added to the persistence context.
Thanks very much for everyone. I have resolved this problem.
I will share my solution, hope it's helpful for you if you are doing same things.
First, my starting point is wrong. Because I use JPA before, so I use acquiescently #EntityListener annotation when I integrate Spring4 and Hibernate5.
Then, I read Hibernate doc and many relevant article and found there is a new way to implement entity listener. See hibernate doc
Finally, my solution is following.
This is my BaseEntity class.
#MappedSuperclass
public class BaseEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false, updatable = false)
private Date createDate;
#Column(nullable = false)
private Date modifyDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
First of all, you need to define EntityListener class.
public class EntityListener implements PreInsertEventListener, PreUpdateEventListener {
private static final String CREATE_DATE_PROPERTY = "createDate";
private static final String MODIFY_DATE_PROPERTY = "modifyDate";
#Override
public boolean onPreInsert(PreInsertEvent event) {
if (event.getEntity() instanceof BaseEntity){
//property name of entity
String[] propertyNames = event.getPersister().getEntityMetamodel().getPropertyNames();
//property value of entity
Object[] state = event.getState();
for (int i = 0; i < propertyNames.length ; i ++) {
if (CREATE_DATE_PROPERTY.equals(propertyNames[i]) || MODIFY_DATE_PROPERTY.equals(propertyNames[i])){
state[i] = new Date();
}
}
}
return false;
}
#Override
public boolean onPreUpdate(PreUpdateEvent event) {
if (event.getEntity() instanceof BaseEntity){
//property name of entity
String[] propertyNames = event.getPersister().getEntityMetamodel().getPropertyNames();
//property value of entity
Object[] state = event.getState();
for (int i = 0; i < propertyNames.length ; i ++) {
if (MODIFY_DATE_PROPERTY.equals(propertyNames[i])){
state[i] = new Date();
}
}
}
return false;
}
}
Last, you should register entity event listener.
#SuppressWarnings("unchecked")
#Component
public class EntityEventListenerRegistry {
#Autowired
private SessionFactory sessionFactory;
/**
* EventListenerRegistry:http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#annotations-jpa-entitylisteners
*/
#PostConstruct
public void registerListeners(){
EventListenerRegistry eventListenerRegistry = ((SessionFactoryImplementor) sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class);
eventListenerRegistry.prependListeners(EventType.PRE_INSERT, EntityListener.class);
eventListenerRegistry.prependListeners(EventType.PRE_UPDATE, EntityListener.class);
}
}

Spring MongoRepository is Null

I have the following code which attempts to save a POJO object (Actor) into MongoDB using Spring Mongo Repository, but the repository object is always Null. I have followed multiple examples but mainly this one
The POJO class:
#Document(collection = "actors")
public class Actor
{
#Id
private String id;
...
//constructor
//setters & getters
}
The repository:
public interface ActorRepository extends MongoRepository<Actor, String>
{
public Actor findByFNameAndLName(String fName, String lName);
public Actor findByFName (String fName);
public Actor findByLName(String lName);
}
The service that uses the repository:
#Service
public class ActorService
{
#Autowired
private ActorRepository actorRepository;
public Actor insert(Actor a)
{
a.setId(null);
return actorRepository.save(a);
}
}
And I access the service from a REST controller class:
#RestController
public class Controllers
{
private static final Logger logger = Logger.getLogger(Controllers.class);
private static final ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringMongoConfig.class);
private ActorService actorService = new ActorService();
#RequestMapping(value="/createActor", method=RequestMethod.POST)
public #ResponseBody String createActor(#RequestParam(value = "fName") String fName,
#RequestParam(value = "lName") String lName,
#RequestParam(value = "role") String role)
{
return actorService.insert(new Actor(null,fName,lName,role)).toString();
}
...
}
The error that I get is NullPointerException from this line: return actorRepository.save(a); in the ActorService.insert() method.
Any Idea why is this happening?
EDIT: Here is the Spring Configurations
#Configuration
public class SpringMongoConfig extends AbstractMongoConfiguration
{
#Bean
public GridFsTemplate gridFsTemplate() throws Exception
{
return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter());
}
#Override
protected String getDatabaseName()
{
return "SEaaS";
}
#Override
#Bean
public Mongo mongo() throws Exception
{
return new MongoClient("localhost" , 27017 );
}
public #Bean MongoTemplate mongoTemplate() throws Exception
{
return new MongoTemplate(mongo(), getDatabaseName());
}
}
The problem is that you are not using Spring to get the ActorService dependency -instead you have manually instantiated the dependency using
private ActorService actorService = new ActorService();.
The following code is the easiest fix in order to inject the ActorService dependency into the controller.
#RestController
public class Controllers
{
private static final Logger logger = Logger.getLogger(Controllers.class);
private static final ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringMongoConfig.class);
#Autowired
private ActorService actorService;
#RequestMapping(value="/createActor", method=RequestMethod.POST)
public #ResponseBody String createActor(#RequestParam(value = "fName") String fName,
#RequestParam(value = "lName") String lName,
#RequestParam(value = "role") String role)
{
return actorService.insert(new Actor(null,fName,lName,role)).toString();
}
...
}

Resources