Not a managed type during app context initialization - spring

I cannot figure out why entity objects cannot be managed by DAO classes.
I have the following PersistenceConfig file:
#Configuration
#EnableTransactionManagement
#PropertySource({"classpath:persistence"})
#EnableJpaRepositories("com.wx.rm")
public class PersistenceConfig {
#Autowired
private Environment env;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(restDataSource());
sessionFactory.setPackagesToScan(new String[]{"com.wx.rm"});
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource restDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties hibernateProperties() {
return new Properties() {
{
setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
setProperty("hibernate.format_sql", env.getProperty("hibernate.format_sql"));
setProperty("hibernate.globally_quoted_identifiers",
env.getProperty("hibernate.globally_quoted_identifiers"));
}
};
}
}
Interface IFooAdvertDao:
#Repository("fooAdvertDao")
public interface IFooAdvertDao extends GenericDao<FooAdvert, String> {
}
Interface IBarAdvertDao:
#Repository("barAdvertDao")
public interface IBarAdvertDao extends GenericDao<BarAdvert, Integer> {
}
Base entity BaseAdvert class:
#MappedSuperclass
public abstract class BaseAdvert implements Serializable{
private static final long serialVersionUID = 1L;
#Column(name = "link")
private String link;
#Column(name = "rooms")
private BigDecimal rooms;
public BaseAdvert() {
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public BigDecimal getRooms() {
return rooms;
}
public void setRooms(BigDecimal rooms) {
this.rooms = rooms;
}
}
Entity FooAdvert class:
#Entity
#Table(name = "foo_adverts")
#DynamicUpdate
public class FooAdvert extends BaseAdvert implements Serializable {
#Id
private String id;
#Column(name = "type")
private Integer type;
public FooAdvert() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
}
Entity BarAdvert class:
#Entity
#Table(name = "bar_adverts")
#DynamicUpdate
public class BarAdvert extends BaseAdvert implements Serializable {
#Id
private Integer id;
#Column(name = "status")
private Integer status;
public BarAdvert() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}
That`s my GenericDao class:
#Repository
public interface GenericDao<T extends Serializable, ID extends Serializable> extends JpaRepository<T, ID> {
}
Generic service class:
public interface GenericService <T extends Serializable, ID extends Serializable> {
T findOne(final ID id);
Page<T> findAll(final Pageable pageable);
long count();
}
Generic service implementation class:
#Service
#Transactional
public class GenericServiceImpl <T extends Serializable, ID extends Serializable> implements GenericService<T, ID> {
#Autowired
private GenericDao<T, ID> genericDao;
public GenericServiceImpl() {
}
public GenericServiceImpl(GenericDao<T, ID> genericDao) {
this.genericDao = genericDao;
}
#Override
#Transactional(readOnly = true)
public T findOne(ID id) {
return genericDao.findOne(id);
}
#Override
#Transactional(readOnly = true)
public Page<T> findAll(Pageable pageable) {
return genericDao.findAll(pageable);
}
#Override
#Transactional(readOnly = true)
public long count() {
return genericDao.count();
}
}
FooAdvertService:
#Service
public class FooAdvertService extends GenericServiceImpl<FooAdvert, String> {
#Autowired
private IFooAdvertDao fooAdvertDao;
}
FooAdvertController class:
#RestController
#RequestMapping("/api")
public class FooAdvertController {
#Autowired
private FooAdvertService fooAdvertService;
#GetMapping("count")
public ResponseEntity getAdvertsCount() {
Long advertsCount = fooAdvertService.count();
return new ResponseEntity(advertsCount, HttpStatus.OK);
}
}
Error message when I try to run my app:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fooAdvertController': Unsatisfied dependency expressed through field 'fooAdvertService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fooAdvertService': Unsatisfied dependency expressed through field 'genericDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fooAdvertDao': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class org.wixanz.rm.ads.domain.FooAdvert
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fooAdvertService': Unsatisfied dependency expressed through field 'genericDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fooAdvertDao': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class org.wixanz.rm.ads.domain.FooAdvert
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fooAdvertDao': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class org.wixanz.rm.ads.domain.FooAdvert
Caused by: java.lang.IllegalArgumentException: Not a managed type: class org.wixanz.rm.ads.domain.FooAdvert
at org.hibernate.jpa.internal.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:210) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]

try to autowire the IFooAdvertDao by name
#Service
public class FooAdvertService extends GenericServiceImpl<FooAdvert, String>
{
#Autowired
#Qualifier("fooAdvertDao")
private IFooAdvertDao fooAdvertDao;
}

Related

Mongo Template querying the wrong collection

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;
}
}

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type

2020-09-23T15:28:00.3483912Z java.lang.IllegalStateException: Failed to load ApplicationContext
2020-09-23T15:28:00.3489821Z Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'salecChannelEventProcessor' defined in file [/home/runner/work/calculation-service/calculation-service/target/classes/com/demo/calculation/saleschannel/SalecChannelEventProcessor.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'de.demo.json.schema.JsonValidator' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
import de.demo.json.schema.JsonValidator;
#Configuration
#ComponentScan( basePackages = {
"com.demo",
"de.demo" },
excludeFilters = {
#ComponentScan.Filter( Configuration.class )
} )
#ImportResource("classpath:/spring-context.xml")
#Import({SwaggerConfig.class, SalesChannelSqsConfig.class})
public class SpringMvcConfig extends WebMvcConfigurationSupport {
#Autowired private ApplicationContext applicationContext;
#Bean( name = "objectMapper" )
public ObjectMapper getObjectMapper( JacksonService jacksonService ) {
return jacksonService.getObjectMapper();
}
#Bean(name = "jsonValidator")
public JsonValidator jsonValidator() {
return new JsonValidator();
}
}
#Component
#Slf4j
#RequiredArgsConstructor
public class SalesChannelUpdateListerner {
#NonNull
private final SalesChannelService salesChannelService;
#NonNull
private final SalecChannelEventProcessor salecChannelEventProcessor;
#SqsListener(value = "${sales.channel.update.queue.name}", deletionPolicy = ON_SUCCESS)
#SneakyThrows
public void receiveSalesChannelUpdateEvent(
#NotificationMessage EnvelopedMessage envelopedMessage) {
log.debug("Received message from sales channel update event queue : {}"
}
#Component
#Slf4j
#RequiredArgsConstructor
public class SalecChannelEventProcessor {
private static final String MESSAGE_TYPE = "sales_channel_update";
#NonNull
private final ObjectMapper objectMapper;
#NonNull
private final JsonValidator jsonValidator;
#SneakyThrows(JsonProcessingException.class)
public boolean isValid(EnvelopedMessage envelopedMessage) {
if (!MESSAGE_TYPE.equals(envelopedMessage.getType())) {
return false;
}
return jsonValidator.validate(envelopedMessage);
}
You need to create the JsonValidator bean. You need to change yor SalecChannelEventProcessor to be:
#Component
#Slf4j
#RequiredArgsConstructor
public class SalecChannelEventProcessor {
private static final String MESSAGE_TYPE = "sales_channel_update";
#NonNull
private final ObjectMapper objectMapper;
#Bean
public JsonValidator jsonValidator(){
return new JsonValidator();
}
#SneakyThrows(JsonProcessingException.class)
public boolean isValid(EnvelopedMessage envelopedMessage) {
if (!MESSAGE_TYPE.equals(envelopedMessage.getType())) {
return false;
}
return jsonValidator().validate(envelopedMessage);
}
}

How to do integration testing for custom mongo repository?

These are the following configuration that I have done in my project.
#Configuration
public class AppMongoConfig {
#Autowired private MongoDbFactory mongoDbFactory;
#Autowired private MongoMappingContext mongoMappingContext;
#Bean
public MappingMongoConverter mappingMongoConverter() {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
return converter;
}
}
#Configuration
#RequiredArgsConstructor
#EnableConfigurationProperties(MultipleMongoProperties.class)
public class MultipleMongoConfig {
private final MultipleMongoProperties mongoProperties;
#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 MongoClientURI(mongo.getUri()));
}
#Bean
public MongoDbFactory secondaryFactory(final MongoProperties mongo) throws Exception {
return new SimpleMongoDbFactory(new MongoClientURI(mongo.getUri()));
}
}
#Data
#ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {
private MongoProperties primary = new MongoProperties();
private MongoProperties secondary = new MongoProperties();
}
#Configuration
#EnableMongoRepositories(
basePackages = {"com.student.repository.primary"},
mongoTemplateRef = "primaryMongoTemplate")
public class PrimaryMongoConfig {}
#Configuration
#EnableMongoRepositories(
basePackages = {"com.student.repository.secondary"},
mongoTemplateRef = "secondaryMongoTemplate")
public class SecondaryMongoConfig {}
Repository code:
public interface StudentDAO {
Student save(StudentInfo studentInfo);
}
#Repository
public class StudentDAOImpl implements StudentDAO {
#Autowired #Qualifier("primaryMongoTemplate")
private MongoTemplate mongoTemplate;
#Override public StudentInfo save(StudentInfo userWatchlist) {
return mongoTemplate.save(userWatchlist);
}
}
Integration Testing code:
#RunWith(SpringRunner.class)
#DataMongoTest(includeFilters = #Filter(Repository.class))
public class WatchListDAOImplIT {
#Autowired private StudentDAO studentDAO;
#Test
public void save() {
StudentInfo studentInfo = getStudentInfo();
StudentInfo dbUserWatchlist = watchListDAO.save(studentInfo);
Assert.assertEquals(studentInfo.getId(), dbUserWatchlist.getId());
}
private StudentInfo getStudentInfo() {
StudentInfo studentInfo = new StudentInfo();
studentInfo.setId(9999999l);
return studentInfo;
}
}
Which is giving me following error:-
java.lang.IllegalStateException: Failed to load ApplicationContext
at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at
org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:
: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'appMongoConfig': Unsatisfied dependency
expressed through field 'mongoDbFactory'; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'primaryFactory' defined in class path
resource [.../config/mongo/MultipleMongoConfig.class]: Unsatisfied
dependency expressed through method 'primaryFactory' parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'org.springframework.boot.autoconfigure.mongo.MongoProperties'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations: {}
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'org.springframework.boot.autoconfigure.mongo.MongoProperties'
available: expected at least 1 bean which

Bad Request : org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Failed to bind request element

First Entity:
#Entity
#Table(name = "PIL_P_DOMAINE")
public class PIL_P_DOMAINE {
#NotBlank
#Column(nullable = false, unique = true, name = "DOMAINE_ID")
private String DOMAINE_ID;
#NotBlank
#Column(nullable = false, name = "DOMAINE_DS")
private String DOMAINE_DS;
public PIL_P_DOMAINE() {
}
}
Second Entity:
#Entity
public class PIL_P_DOMAINE_TABLE {
#NotBlank
#JoinColumn(nullable = false, name = "DOMAINE_ID")
#ManyToOne
private PIL_P_DOMAINE DOMAINE_ID;
#NotBlank
#Column(nullable = false, name = "DATABASE_NM")
private String DATABASE_NM;
#NotBlank
#Column(nullable = false, name = "TABLE_NM")
private String TABLE_NM;
#Column(name = "APPLCTN_COLNM_NM")
private String APPLCTN_COLNM_NM;
#Column(name = "CRITERE_FILTRE_NM")
private String CRITERE_FILTRE_NM;
public PIL_P_DOMAINE_TABLE() {
}
}
Converter:
#Component("domaineToDomTabConverter")
public class DomaineToDomTabConverter implements Converter<Object, PIL_P_DOMAINE> {
static final Logger logger = LoggerFactory.getLogger(DomaineToDomTabConverter.class);
#Autowired
#Qualifier("pIL_P_DOMAINE_SERVICE")
IService<PIL_P_DOMAINE> domService;
/**
*
*
* #see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
public PIL_P_DOMAINE convert(Object element) {
Integer id = Integer.parseInt((String) element);
PIL_P_DOMAINE dom = domService.findById(id);
logger.info("Domaine : {}", dom);
return dom;
}
}
AppConfig:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.fussa.fyby")
public class AppConfig extends WebMvcConfigurerAdapter {
#Autowired
DomaineToDomTabConverter domaineToDomTabConverter;
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(domaineToDomTabConverter);
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Override
public void configurePathMatch(PathMatchConfigurer matcher) {
matcher.setUseRegisteredSuffixPatternMatch(true);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
when i try to persist an PIL_P_DOMAINE object whitout adding
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(domaineToDomTabConverter);
}
to my AppConfig class , to object is persisted (y).
The issue i have is when i want to persist an PIL_P_DOMAINE_TABLE object which contain an object PIL_P_DOMAINE, i added DomaineToDomTabConverter to convert to string i will get in form to the object so i added the converter in my AppCongig class,with those modifications i cant persist an PIL_P_DOMAINE object, i got this error:
WARN :
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
- Failed to bind request element: org.springframework.beans.TypeMismatchException: Failed to convert
value of type [com.fussa.fyby.model.PIL_P_DOMAINE] to required type
[com.fussa.fyby.model.PIL_P_DOMAINE]; nested exception is
org.springframework. core.convert.ConversionFailedException: Failed to
convert from type [com.fussa.fyby.model.PIL_P_DOMAINE] to type
[#javax.validation.Valid #org.springframework.web.bi
nd.annotation.ModelAttribute com.fussa.fyby.model.PIL_P_DOMAINE] for
value 'com.fussa.fyby.model.PIL_P_DOMAINE#716898c0'; nested exception
is java.lang.ClassCastExce ption: com.fussa.fyby.model.PIL_P_DOMAINE
cannot be cast to java.lang.String
How can i call the converter only if i want to persist my second entity and not the first ?
Thanks for any advices..
This issue was fixed by Parameterizing the type i'm converting from to String instead of Object
#Component("domaineToDomTabConverter")
public class DomaineToDomTabConverter implements Converter<String, PIL_P_DOMAINE> {
public PIL_P_DOMAINE convert(Stringelement) {
//
}
}

spring injection issues with spring data

I am getting the following error
Error creating bean with name 'genericRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
I am new to generics, if there are any generics issue please let me know as well
my Contact.java is in com.merc.template.managelistofobjects.domain package
All other classes are in com.merc.template.managelistofobjects package
ContactCollectionManagerImpl
#Component
public class ContactCollectionManagerImpl extends CollectionManagerImpl<Contact> implements CollectionManager<Contact>{
#Autowired
private GenericRepository<Contact,Long> genericRepository;
public ContactCollectionManagerImpl() {
setGenericRepository(genericRepository);
}
#Override
public void addToCollection(Contact contact, boolean reload){
super.addToCollection(contact, entityDataMap, reload);
}
}
CollectionManagerImpl
public abstract class CollectionManagerImpl<T extends EntityBean> implements CollectionManager<T>{
private GenericRepository objectManager;
public void setGenericRepository(GenericRepository genericRepository) {
this.objectManager = genericRepository;
}
protected void addToCollection(T entity, Map<Long,T> entityDataMap, boolean reload) {
//reload is set to false when the static map needs not be updated
if(reload){
//loads all the existing collection objects from db
loadCollection(entityDataMap, false);
//check if the obect to be inserted already exists in collection
if(entityDataMap.containsKey(entity.getId())){
return;
}
}
//TODO save to database
objectManager.save(entity);
if(reload){
syncCollectionWithDB(entityDataMap);
}
}
}
CollectionManager
public interface CollectionManager<T> {
public void addToCollection(T object, boolean reload);
}
GenericRepository
public interface GenericRepository<T, ID extends Long> extends JpaRepository<T, ID>{
}
MyApplicationContext
#Configuration
#EnableJpaRepositories
#ComponentScan("com.merc.template.managelistofobjects")
#ImportResource("classpath:spring/app-context.xml")
#PropertySource("classpath:application.properties")
public class MyApplicationContext {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
#Resource
private Environment environment;
#Bean
public DataSource dataSource() {
BoneCPDataSource dataSource = new BoneCPDataSource();
dataSource.setDriverClass(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setJdbcUrl(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public JpaTransactionManager transactionManager() throws ClassNotFoundException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
return transactionManager;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() throws ClassNotFoundException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
//setPackagesToScan = com.merc.template.managelistofobjects.domain
entityManagerFactoryBean.setPackagesToScan(environment.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);
Properties jpaProterties = new Properties();
jpaProterties.put(PROPERTY_NAME_HIBERNATE_DIALECT, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
jpaProterties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
jpaProterties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));
jpaProterties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
entityManagerFactoryBean.setJpaProperties(jpaProterties);
return entityManagerFactoryBean;
}
#Bean
public CollectionManager contactCollectionManager(){
return new ContactCollectionManagerImpl();
}
}
My main class contains the following code
ApplicationContext context = new AnnotationConfigApplicationContext(MyApplicationContext.class);
CollectionManager collMgr = context.getBean("contactCollectionManager",CollectionManager.class);
Contact contact = new Contact(2L,"xyz","abc");
collMgr.addToCollection(contact, true);
entitymanager.packages.to.scan=com.merc.template.managelistofobjects.domain
my spring xml file contains just one line
<jpa:repositories base-package="com.merc.template.managelistofobjects"/>
When i run the code I get the following error
java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
You cannot autowire an object that takes an generic type, You will have to define a strongly typed sub interface of GenericRepository and then autowire it inside your clases
public interface ContactGenericRepository extends GenericRepository<Contact,Long> {}
Then autowire the new interface
#Autowired
private ContactGenericRepository contractGenericRepository;
P.S: you cannot use the autowired object inside the constructor of the class that wrap it, as you are doing inside the ContactCollectionManagerImpl constructor, as the object is not instantiated yet
You could easily use #PostConstruct on any other method that does that behaviour you want, like this
#PostConstruct
public void populateContactCollectionManagerImpl() {
setGenericRepository(genericRepository);
}

Resources