Skip to content

Instantly share code, notes, and snippets.

@BenDol
Last active October 6, 2016 21:14
Show Gist options
  • Save BenDol/080169ee25e8d4f231f4 to your computer and use it in GitHub Desktop.
Save BenDol/080169ee25e8d4f231f4 to your computer and use it in GitHub Desktop.
The cyclic dependency issue with Spring 4 (worked fine in Spring 3)
@Service("emailService")
public class EmailServiceImpl extends MailServiceImpl implements EmailService, InitializingBean {
private static final long serialVersionUID = -7973057973637014852L;
private static final Logger logger = Logger.getLogger(EmailServiceImpl.class.getName());
@Autowired
private EntityMapperContext mapperContext;
@Autowired
private HibernateDao hibernateDao;
@Autowired
private SettingService settingService;
// Used for manual transaction implementation
@Autowired
private TransactionTemplate transactionTemplate;
.. snip ..
}
/**
* Maps the applications entities and models
* @author Ben Dol
*/
public class EntityMapperContext extends AnnotationMapperContext<AnnotationDozerBeanMapper> {
@Autowired(required=false)
private PersonLdapDao personLdapDao;
@Autowired(required=false)
private SectionLdapDao sectionLdapDao;
@Autowired(required=false)
private UserService userService;
@Autowired(required=false)
private PersonService personService;
@Autowired(required=false)
private EventService eventService;
.. snip ..
}
@Service("eventService")
public class EventServiceImpl extends RemoteServiceServlet implements EventService, InitializingBean {
private static final long serialVersionUID = -514090558278100765L;
private static final Logger logger = Logger.getLogger(EventServiceImpl.class.getName());
@Autowired
private HibernateEntityService entityService;
@Autowired
private EmailService emailService;
@Autowired
private UserService userService;
@Autowired
private NotificationService notificationService;
@Autowired
private ActionDao actionDao;
@Autowired
private RequestProvider requestProvider;
// Used for manual transaction implementation
@Autowired
private TransactionTemplate transactionTemplate;
.. snip ..
}
@Configuration
@Import({
PropertiesModule.class,
DatabaseModule.class,
MappingModule.class
})
@EnableTransactionManagement
public class HibernateModule {
@Autowired
private DatabaseModule databaseModule;
private static int statisticId = 0;
private @Value("${root.path}") String projectPath;
private @Value("${hibernate.dialect}") String hibernateDialect;
private @Value("${hibernate.hbm2ddl}") String hibernateHbm2dll;
private @Value("${hibernate.show_sql}") String hibernateShowSql;
private @Value("${hibernate.format_sql}") String hibernateFormatSql;
private @Value("${hibernate.generate_statistics}") String hibarnateStatistics;
private @Value("${hibernate.cache.provider_class}") String hibarnateCacheProviderClass;
private @Value("${hibernate.cache.use_query_cache}") String hibarnateQueryCache;
private @Value("${hibernate.cache.use_second_level_cache}") String hibarnateSecondLevelCache;
private @Value("${hibernate.cache.use_structured_entries}") String hibernateStructuredEntries;
private @Value("${net.sf.ehcache.configurationResourceName}") String hibernateEhcacheResource;
@Bean(name="sessionFactory")
@DependsOn("dataSource")
public AnnotationSessionFactoryBean sessionFactory() {
AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean();
sessionFactory.setDataSource((DataSource) databaseModule.dataSource().getObject());
sessionFactory.setPackagesToScan(
projectPath + ".server.entities",
projectPath + ".server.entities.joins");
Properties props = new Properties();
props.setProperty("hibernate.dialect", hibernateDialect);
props.setProperty("hibernate.show_sql", hibernateShowSql);
props.setProperty("hibernate.hbm2ddl.auto", hibernateHbm2dll);
props.setProperty("hibernate.format_sql", hibernateFormatSql);
props.setProperty("hibernate.generate_statistics", hibarnateStatistics);
props.setProperty("hibernate.cache.provider_class", hibarnateCacheProviderClass);
props.setProperty("hibernate.cache.use_query_cache", hibarnateQueryCache);
props.setProperty("hibernate.hibernate.cache.provider_configuration_file_resource_path", hibernateEhcacheResource);
props.setProperty("hibernate.use_second_level_cache", hibarnateSecondLevelCache);
props.setProperty("hibernate.cache.use_structured_entries", hibernateStructuredEntries);
props.setProperty("javax.persistence.validation.mode", "none");
// caching resource
//props.setProperty("net.sf.ehcache.configurationResourceName", hibernateEhcacheResource);
//props.setProperty("hibernate.transaction.manager_lookup_class", "nz.co.doltech.actions.server.persistence.TransactionManagerLookup");
//props.setProperty("hibernate.transaction.factory_class", "org.hibernate.transaction.JTATransactionFactory");
sessionFactory.setHibernateProperties(props);
return sessionFactory;
}
@Bean(name="transactionManager")
@DependsOn("sessionFactory")
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
@Bean(name="hibernateTemplate")
@DependsOn("sessionFactory")
public HibernateTemplate hibernateTemplate() {
HibernateTemplate hibernateTemplate = new HibernateTemplate();
hibernateTemplate.setSessionFactory(sessionFactory().getObject());
return hibernateTemplate;
}
@Bean(name="jmxExporter")
@DependsOn("hibernateStatisticsBean")
public MBeanExporter jmxExporter() {
MBeanExporter exporter = new MBeanExporter();
Map<String, Object> map = new HashMap<>();
Properties props = AppProperties.getProperties();
String name = props.getProperty(AppProperties.CLIENT_MODULE_NAME);
String type = props.getProperty(AppProperties.CLIENT_RELEASE_STAGE);
map.put("Hibernate:"+name+"[" + ++statisticId + "]-"+type+"=Statistics",
hibernateStatisticsBean());
exporter.setBeans(map);
return exporter;
}
@Bean(name="hibernateStatisticsBean")
public StatisticsService hibernateStatisticsBean() {
StatisticsService statsBean = new StatisticsService();
statsBean.setStatisticsEnabled(true);
statsBean.setSessionFactory(sessionFactory().getObject());
return statsBean;
}
@Bean(name="entityService")
@DependsOn({"mapperFactory", "hibernateDao"})
public HibernateEntityService entityService() {
return new HibernateEntityServiceImpl(hibernateDao());
}
@Bean(name="hibernateDao")
@DependsOn({"hibernateTemplate"})
public HibernateDao hibernateDao() {
return new HibernateDao(hibernateTemplate());
}
@Bean(name="actionDao")
@DependsOn("hibernateTemplate")
public ActionHibernateDao actionDao() {
return new ActionHibernateDao(hibernateTemplate());
}
@Bean(name="transactionTemplate")
@DependsOn({"transactionManager"})
@Scope("prototype")
public TransactionTemplate transactionTemplate() {
return new TransactionTemplate(transactionManager());
}
}
@Configuration
@Import({PropertiesModule.class})
public class MappingModule {
private @Value("${root.path}") String projectPath;
@Lazy
@Bean(name="mapperContext")
public EntityMapperContext mapperContext() {
String[] packagesToScan = {
projectPath + ".shared.models",
projectPath + ".shared.models.joins"
};
return new EntityMapperContext(packagesToScan);
}
@Lazy
@Bean(name="mapperFactory")
@DependsOn({"mapperContext"})
public EntityMapperFactory mapperFactory() {
return mapperContext().getFactory();
}
}
@Service("settingService")
public class SettingServiceImpl extends RemoteServiceServlet implements SettingService {
private static final long serialVersionUID = 6533139871583927801L;
@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(SettingServiceImpl.class.getName());
@Autowired
private HibernateEntityService entityService;
@Autowired
private EmailService emailService;
.. snip ..
}
@BenDol
Copy link
Author

BenDol commented May 12, 2015

SettingServiceImpl.java#L13 & EmailServiceImpl.java#L15 is where there is a "cyclic" dependency, but this was working fine previously and should still work fine in Spring 4.

@BenDol
Copy link
Author

BenDol commented May 12, 2015

Entry point for the web application: https://gist.github.com/BenDol/d3a73e9d9cb16325b2f5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment