aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2013-04-11 10:13:44 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2013-04-11 10:13:44 +0200
commitcd99d57cccb88ea8a058eca530d62a81a665983c (patch)
tree80d8724872f757876da0fc8dccd409dd5693f19c /src/main
downloadquartz-based-queue-cd99d57cccb88ea8a058eca530d62a81a665983c.tar.gz
quartz-based-queue-cd99d57cccb88ea8a058eca530d62a81a665983c.tar.bz2
quartz-based-queue-cd99d57cccb88ea8a058eca530d62a81a665983c.tar.xz
quartz-based-queue-cd99d57cccb88ea8a058eca530d62a81a665983c.zip
o Initial import.
Diffstat (limited to 'src/main')
-rwxr-xr-xsrc/main/java/io/trygvis/Main.java62
-rwxr-xr-xsrc/main/java/io/trygvis/MyJob.java38
-rwxr-xr-xsrc/main/java/io/trygvis/data/QueueRepository.java8
-rwxr-xr-xsrc/main/java/io/trygvis/data/TaskRepository.java7
-rwxr-xr-xsrc/main/java/io/trygvis/model/Article.java57
-rwxr-xr-xsrc/main/java/io/trygvis/model/Queue.java46
-rwxr-xr-xsrc/main/java/io/trygvis/model/Task.java32
-rwxr-xr-xsrc/main/java/io/trygvis/queue/AsyncService.java18
-rwxr-xr-xsrc/main/java/io/trygvis/queue/JpaAsyncService.java246
-rwxr-xr-xsrc/main/java/io/trygvis/spring/Config.java174
-rwxr-xr-xsrc/main/resources/applicationContext.xml22
-rwxr-xr-xsrc/main/resources/logback.xml28
12 files changed, 738 insertions, 0 deletions
diff --git a/src/main/java/io/trygvis/Main.java b/src/main/java/io/trygvis/Main.java
new file mode 100755
index 0000000..19167d7
--- /dev/null
+++ b/src/main/java/io/trygvis/Main.java
@@ -0,0 +1,62 @@
+package io.trygvis;
+
+import io.trygvis.queue.*;
+import org.hibernate.dialect.*;
+import org.slf4j.*;
+import org.slf4j.bridge.*;
+import org.springframework.beans.factory.annotation.*;
+import org.springframework.context.support.*;
+import org.springframework.stereotype.*;
+import org.springframework.transaction.annotation.*;
+
+import static java.lang.System.*;
+
+@Component
+@Transactional
+public class Main {
+ private static final Logger log = LoggerFactory.getLogger(Main.class);
+
+ public static void main(String[] args) throws Exception {
+ SLF4JBridgeHandler.install();
+
+ String username = getProperty("user.name");
+ setProperty("database.url", getProperty("jdbc.url", "jdbc:postgresql://localhost/" + username));
+ setProperty("database.username", username);
+ setProperty("database.password", username);
+ setProperty("hibernate.showSql", "true");
+ setProperty("hibernate.hbm2ddl.auto", "create"); // create
+ setProperty("hibernate.dialect", PostgreSQL82Dialect.class.getName());
+
+ log.info("Starting context");
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
+ context.start();
+ log.info("Started context");
+
+ try {
+ context.getBean(Main.class).run();
+ log.info("Sleeping");
+ Thread.sleep(1000 * 1000);
+ } catch (Exception e) {
+ e.printStackTrace(System.out);
+ }
+
+ log.info("Stopping context");
+ context.stop();
+ log.info("Stopped context");
+
+ exit(0);
+ }
+
+ @Autowired
+ private AsyncService<AsyncService.QueueRef, AsyncService.ExecutionRef> asyncService;
+
+ public void run() throws Exception {
+ log.info("Main.run");
+
+ asyncService.registerQueue("test-queue", 1, MyJob.class);
+
+ AsyncService.QueueRef queue = asyncService.getQueue("test-queue");
+
+ AsyncService.ExecutionRef executionRef = asyncService.schedule(queue);
+ }
+}
diff --git a/src/main/java/io/trygvis/MyJob.java b/src/main/java/io/trygvis/MyJob.java
new file mode 100755
index 0000000..7303a33
--- /dev/null
+++ b/src/main/java/io/trygvis/MyJob.java
@@ -0,0 +1,38 @@
+package io.trygvis;
+
+import io.trygvis.model.*;
+import org.quartz.*;
+import org.slf4j.*;
+
+import java.util.*;
+import javax.persistence.*;
+
+public class MyJob implements Job {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ public void execute(JobExecutionContext context) throws JobExecutionException {
+ log.info("MyJob.execute: BEGIN");
+ log.info("entityManager = {}", entityManager);
+ log.info("context.getJobDetail().getKey() = {}", context.getJobDetail().getKey());
+
+/*
+ Date now = new Date();
+
+ log.info("now = {}", now);
+
+// Article article = entityManager.find(Article.class, 1);
+//
+// System.out.println("article = " + article);
+// article.setUpdated(now);
+// entityManager.persist(article);
+
+ Article article = new Article(new Date(), null, "title", "body");
+ entityManager.persist(article);
+*/
+
+ log.info("MyJob.execute: END");
+ }
+}
diff --git a/src/main/java/io/trygvis/data/QueueRepository.java b/src/main/java/io/trygvis/data/QueueRepository.java
new file mode 100755
index 0000000..143d747
--- /dev/null
+++ b/src/main/java/io/trygvis/data/QueueRepository.java
@@ -0,0 +1,8 @@
+package io.trygvis.data;
+
+import io.trygvis.model.*;
+import org.springframework.data.jpa.repository.*;
+
+public interface QueueRepository extends JpaRepository<Queue, Long> {
+ Queue findByName(String name);
+}
diff --git a/src/main/java/io/trygvis/data/TaskRepository.java b/src/main/java/io/trygvis/data/TaskRepository.java
new file mode 100755
index 0000000..0b65199
--- /dev/null
+++ b/src/main/java/io/trygvis/data/TaskRepository.java
@@ -0,0 +1,7 @@
+package io.trygvis.data;
+
+import io.trygvis.model.*;
+import org.springframework.data.jpa.repository.*;
+
+public interface TaskRepository extends JpaRepository<Task, Long> {
+}
diff --git a/src/main/java/io/trygvis/model/Article.java b/src/main/java/io/trygvis/model/Article.java
new file mode 100755
index 0000000..6383e50
--- /dev/null
+++ b/src/main/java/io/trygvis/model/Article.java
@@ -0,0 +1,57 @@
+package io.trygvis.model;
+
+import java.util.Date;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+@Entity
+public class Article {
+ @Id
+ @SequenceGenerator(name="id_seq", sequenceName="id_seq")
+ @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_seq")
+ private Integer id;
+ private Date created;
+ private Date updated;
+ private String title;
+ private String body;
+
+ @SuppressWarnings("UnusedDeclaration")
+ private Article() {
+ }
+
+ public Article(Date created, Date updated, String title, String body) {
+ this.created = created;
+ this.updated = updated;
+ this.title = title;
+ this.body = body;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ public Date getUpdated() {
+ return updated;
+ }
+
+ public void setUpdated(Date updated) {
+ this.updated = updated;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getBody() {
+ return body;
+ }
+}
diff --git a/src/main/java/io/trygvis/model/Queue.java b/src/main/java/io/trygvis/model/Queue.java
new file mode 100755
index 0000000..52c5c0f
--- /dev/null
+++ b/src/main/java/io/trygvis/model/Queue.java
@@ -0,0 +1,46 @@
+package io.trygvis.model;
+
+import javax.persistence.*;
+
+@Entity
+@Table(
+ uniqueConstraints = {
+ @UniqueConstraint(name = "uq_queue__name", columnNames = "name")
+ }
+)
+public class Queue {
+
+ @Id
+ @SequenceGenerator(name = "queue_seq", sequenceName = "queue_seq")
+ @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "queue_seq")
+ private Integer id;
+
+ private String name;
+
+ private long interval;
+
+ public Queue(String name, long interval) {
+ this.name = name;
+ this.interval = interval;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getInterval() {
+ return interval;
+ }
+
+ public void setInterval(long interval) {
+ this.interval = interval;
+ }
+}
diff --git a/src/main/java/io/trygvis/model/Task.java b/src/main/java/io/trygvis/model/Task.java
new file mode 100755
index 0000000..fa44e26
--- /dev/null
+++ b/src/main/java/io/trygvis/model/Task.java
@@ -0,0 +1,32 @@
+package io.trygvis.model;
+
+import javax.persistence.*;
+
+@Entity
+public class Task {
+ @Id
+ @SequenceGenerator(name = "task_seq", sequenceName = "task_seq")
+ @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "task_seq")
+ private Integer id;
+
+ @ManyToOne
+ private Queue queue;
+
+ private Long long1;
+
+ public Task(Queue queue) {
+ this.queue = queue;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public Long getLong1() {
+ return long1;
+ }
+
+ public void setLong1(Long long1) {
+ this.long1 = long1;
+ }
+}
diff --git a/src/main/java/io/trygvis/queue/AsyncService.java b/src/main/java/io/trygvis/queue/AsyncService.java
new file mode 100755
index 0000000..dcbe991
--- /dev/null
+++ b/src/main/java/io/trygvis/queue/AsyncService.java
@@ -0,0 +1,18 @@
+package io.trygvis.queue;
+
+import org.quartz.*;
+
+public interface AsyncService<QueueRef extends AsyncService.QueueRef, ExecutionRef extends AsyncService.ExecutionRef> {
+
+ void registerQueue(String name, int interval, Class klass) throws SchedulerException;
+
+ QueueRef getQueue(String name);
+
+ ExecutionRef schedule(QueueRef queue);
+
+ interface QueueRef {
+ }
+
+ interface ExecutionRef {
+ }
+}
diff --git a/src/main/java/io/trygvis/queue/JpaAsyncService.java b/src/main/java/io/trygvis/queue/JpaAsyncService.java
new file mode 100755
index 0000000..2d6c2df
--- /dev/null
+++ b/src/main/java/io/trygvis/queue/JpaAsyncService.java
@@ -0,0 +1,246 @@
+package io.trygvis.queue;
+
+import io.trygvis.data.QueueRepository;
+import io.trygvis.data.TaskRepository;
+import io.trygvis.model.Queue;
+import org.quartz.Job;
+import org.quartz.JobDataMap;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.quartz.JobKey;
+import org.quartz.JobPersistenceException;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerContext;
+import org.quartz.SchedulerException;
+import org.quartz.SchedulerFactory;
+import org.quartz.SimpleScheduleBuilder;
+import org.quartz.SimpleTrigger;
+import org.quartz.TriggerBuilder;
+import org.quartz.impl.DirectSchedulerFactory;
+import org.quartz.impl.JobDetailImpl;
+import org.quartz.impl.StdSchedulerFactory;
+import org.quartz.impl.jdbcjobstore.JobStoreSupport;
+import org.quartz.impl.jdbcjobstore.JobStoreTX;
+import org.quartz.impl.jdbcjobstore.PostgreSQLDelegate;
+import org.quartz.spi.JobStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.jdbc.datasource.DataSourceUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
+
+import javax.annotation.PostConstruct;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.RollbackException;
+import javax.persistence.TypedQuery;
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Properties;
+
+import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
+
+@SuppressWarnings("SpringJavaAutowiringInspection")
+@Component
+public class JpaAsyncService implements AsyncService<JpaAsyncService.JpaQueueRef, JpaAsyncService.JpaExecutionRef> {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ @Autowired
+ private DataSource dataSource;
+
+ private static DataSource dataSourceStatic;
+
+ @Autowired
+ private PlatformTransactionManager transactionManager;
+
+ private static PlatformTransactionManager transactionManagerStatic;
+
+ @Autowired
+ private QueueRepository queueRepository;
+
+ @Autowired
+ private TaskRepository taskRepository;
+
+ private Scheduler scheduler;
+
+ @PostConstruct
+ public void afterPropertiesSet() throws Exception {
+ transactionManagerStatic = transactionManager;
+ dataSourceStatic = dataSource;
+ log.info("afterPropertiesSet!!");
+ Properties quartzProperties = new Properties();
+ quartzProperties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_CLASS, JobStoreTX.class.getName());
+ quartzProperties.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME, "queue");
+ quartzProperties.setProperty(StdSchedulerFactory.PROP_SCHED_SKIP_UPDATE_CHECK, "true");
+ quartzProperties.setProperty(StdSchedulerFactory.PROP_SCHED_SKIP_UPDATE_CHECK, "true");
+// quartzProperties.setProperty(StdSchedulerFactory.PROP_DATASOURCE_PREFIX, "wat");
+ quartzProperties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_CLASS, JpaDataSourceJobStore.class.getName());
+ quartzProperties.setProperty("org.quartz.threadPool.threadCount", "10");
+ quartzProperties.setProperty("org.quartz.jobStore.driverDelegateClass", PostgreSQLDelegate.class.getName());
+ quartzProperties.setProperty("org.quartz.scheduler.jmx.export", "true");
+ SchedulerFactory schedulerFactory = new StdSchedulerFactory(quartzProperties);
+
+ Scheduler s = schedulerFactory.getScheduler();
+ System.out.println("s.getSchedulerName() = " + s.getSchedulerName());
+ scheduler = schedulerFactory.getScheduler("queue");
+ }
+
+ @Transactional
+ public void registerQueue(String name, int interval, Class klass) throws SchedulerException {
+
+ Queue q = queueRepository.findByName(name);
+
+ if (q == null) {
+ Queue queue = new Queue(name, interval);
+ queueRepository.save(queue);
+ } else {
+ boolean dirty = false;
+ if (interval != q.getInterval()) {
+ q.setInterval(interval);
+ dirty = true;
+ }
+
+ if (dirty) {
+ queueRepository.save(q);
+ }
+ }
+
+ JobDetailImpl jobDetail = new JobDetailImpl();
+ JobKey jobKey = JobKey.jobKey("queue-" + name);
+
+ jobDetail.setKey(jobKey);
+ jobDetail.setJobClass(AsyncServiceJob.class);
+ jobDetail.setDurability(true);
+ JobDataMap map = new JobDataMap();
+ map.put("class", klass.getName());
+ jobDetail.setJobDataMap(map);
+
+ scheduler.addJob(jobDetail, true);
+
+ SimpleScheduleBuilder schedule = simpleSchedule().
+ repeatForever().
+ withIntervalInSeconds(interval);
+
+ SimpleTrigger trigger = TriggerBuilder.newTrigger().
+ withSchedule(schedule).
+ withIdentity(jobKey.getName()).
+ forJob(jobKey).
+ build();
+
+ scheduler.scheduleJob(trigger);
+ }
+
+ @Transactional(readOnly = true)
+ public JpaQueueRef getQueue(String name) {
+ TypedQuery<Queue> query = entityManager.createQuery("select q from io.trygvis.model.Queue q where name = ?1", Queue.class);
+ query.setParameter(1, name);
+ List<Queue> list = query.getResultList();
+ System.out.println("list.size() = " + list.size());
+
+ if (list.size() == 0) {
+ throw new RollbackException("No such queue: '" + name + "'.");
+ }
+
+ Queue queue = list.get(0);
+
+ entityManager.detach(query);
+
+ return new JpaQueueRef(queue);
+ }
+
+ @Transactional
+ public JpaExecutionRef schedule(JpaQueueRef queue) {
+ return null;
+ }
+
+ static class JpaQueueRef implements AsyncService.QueueRef {
+ public final Queue queue;
+
+ JpaQueueRef(Queue queue) {
+ this.queue = queue;
+ }
+ }
+
+ static class JpaExecutionRef implements AsyncService.ExecutionRef {
+ }
+
+ public static class AsyncServiceJob implements Job {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ public void execute(JobExecutionContext context) throws JobExecutionException {
+ try {
+ log.info("Running");
+
+ SchedulerContext map = context.getScheduler().getContext();
+ ApplicationContext applicationContext = (ApplicationContext) map.get("applicationContext");
+
+ log.info("applicationContext = {}", applicationContext);
+
+ String className = map.getString("class");
+
+ log.info("className = {}", className);
+
+ Class klass = getClass().getClassLoader().loadClass(className);
+ Object bean = applicationContext.getBean(klass);
+
+ log.info("bean = {}", bean);
+ } catch (Exception e) {
+ log.warn("fail", e);
+ throw new JobExecutionException(e, false);
+ }
+ }
+ }
+
+ public static class JpaDataSourceJobStore extends JobStoreSupport {
+
+ public JpaDataSourceJobStore() {
+ setDataSource("wat");
+ }
+
+ protected Connection getNonManagedTXConnection() throws JobPersistenceException {
+// DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
+// definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
+// TransactionStatus transaction = transactionManagerStatic.getTransaction(definition);
+
+ System.out.println("dataSourceStatic = " + dataSourceStatic);
+ Connection c = DataSourceUtils.getConnection(dataSourceStatic);
+ try {
+ c.setAutoCommit(false);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ System.out.println("c = " + c);
+
+ return c;
+ }
+
+ protected void closeConnection(Connection c) {
+ try {
+ DataSourceUtils.doCloseConnection(c, dataSourceStatic);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ protected Object executeInLock(String lockName, TransactionCallback txCallback) throws JobPersistenceException {
+ return executeInNonManagedTXLock(lockName, txCallback);
+ }
+ }
+}
diff --git a/src/main/java/io/trygvis/spring/Config.java b/src/main/java/io/trygvis/spring/Config.java
new file mode 100755
index 0000000..9a968e0
--- /dev/null
+++ b/src/main/java/io/trygvis/spring/Config.java
@@ -0,0 +1,174 @@
+package io.trygvis.spring;
+
+import com.jolbox.bonecp.*;
+import io.trygvis.MyJob;
+import io.trygvis.model.*;
+import org.hibernate.*;
+import org.hibernate.annotations.*;
+import org.hibernate.cfg.*;
+import org.hibernate.ejb.*;
+import org.quartz.*;
+import org.quartz.impl.jdbcjobstore.*;
+import org.quartz.spi.*;
+import org.springframework.beans.factory.annotation.*;
+import org.springframework.context.annotation.*;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.support.*;
+import org.springframework.data.jpa.repository.config.*;
+import org.springframework.jdbc.datasource.*;
+import org.springframework.orm.hibernate4.*;
+import org.springframework.orm.jpa.*;
+import org.springframework.scheduling.quartz.*;
+import org.springframework.transaction.*;
+import org.springframework.transaction.annotation.*;
+import org.springframework.transaction.support.*;
+
+import java.util.*;
+import javax.persistence.*;
+import javax.sql.*;
+
+import static org.hibernate.cfg.AvailableSettings.*;
+import static org.hibernate.ejb.AvailableSettings.*;
+
+@Configuration
+@ComponentScan(basePackages = "io.trygvis")
+@EnableTransactionManagement
+@EnableJpaRepositories(basePackages = "io.trygvis.data")
+public class Config {
+
+ @Bean
+ public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws Exception {
+ return new PropertySourcesPlaceholderConfigurer() {{
+// setLocation(new UrlResource("file:environment.properties"));
+ setProperties(System.getProperties());
+ setLocalOverride(true);
+ }};
+ }
+
+// public SpringBeanJobFactory springBeanJobFactory() {
+// SpringBeanJobFactory factory = new SpringBeanJobFactory();
+// return factory;
+// }
+
+/*
+ @Bean
+ public SchedulerFactoryBean quartz(DataSource dataSource, PlatformTransactionManager transactionManager) {
+ SchedulerFactoryBean bean = new SchedulerFactoryBean();
+ bean.setApplicationContextSchedulerContextKey("applicationContext");
+ bean.setDataSource(dataSource);
+ bean.setTransactionManager(transactionManager);
+// bean.setJobFactory(new JobFactory() {
+// public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
+// Class<? extends Job> klass = bundle.getJobDetail().getJobClass();
+// }
+// });
+
+ Properties quartzProperties = new Properties();
+ quartzProperties.setProperty("org.quartz.scheduler.skipUpdateCheck", "true");
+// quartzProperties.setProperty("org.quartz.jobStore.selectWithLockSQL", "false");
+ quartzProperties.setProperty("org.quartz.jobStore.driverDelegateClass", PostgreSQLDelegate.class.getName());
+ quartzProperties.setProperty("org.quartz.scheduler.jmx.export", "true");
+ bean.setQuartzProperties(quartzProperties);
+ return bean;
+ }
+*/
+
+ // This turns out to be fairly useless as Spring won't register them automatically.
+ // It's probably better to use @Scheduled/@Async instead
+ /*
+ @Bean(name = "my-job")
+ public JobDetailFactoryBean myJobDetailBean() {
+ JobDetailFactoryBean bean = new JobDetailFactoryBean();
+ bean.setJobClass(MyJob.class);
+ bean.setDurability(true);
+
+ return bean;
+ }
+
+ @Bean
+ public CronTriggerFactoryBean myJobTrigger(JobDetail jobDetail) {
+ CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
+ bean.setName("my-trigger");
+ bean.setBeanName("my-job");
+ bean.setJobDetail(jobDetail);
+ bean.setCronExpression("0/10 * * * * ?");
+
+ return bean;
+ }
+ */
+
+ @Bean
+ public DataSource dataSource(@Value("${database.url}") String jdbcUrl,
+ @Value("${database.username}") String username,
+ @Value("${database.password}") String password) {
+ BoneCPDataSource ds = new BoneCPDataSource();
+
+ ds.setLogStatementsEnabled(true);
+
+ ds.setJdbcUrl(jdbcUrl);
+ ds.setUsername(username);
+ ds.setPassword(password);
+
+ ds.setIdleConnectionTestPeriodInSeconds(60);
+ ds.setIdleMaxAgeInSeconds(240);
+ ds.setMaxConnectionsPerPartition(40);
+ ds.setMinConnectionsPerPartition(0);
+ ds.setPartitionCount(1);
+ ds.setAcquireIncrement(1);
+ ds.setStatementsCacheSize(1000);
+ ds.setReleaseHelperThreads(3);
+ ds.setStatisticsEnabled(true);
+ return new TransactionAwareDataSourceProxy(new LazyConnectionDataSourceProxy(ds));
+ }
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
+ @Value("${hibernate.hbm2ddl.auto}") String hbm2ddl,
+ @Value("${hibernate.showSql}") boolean showSql,
+ @Value("${hibernate.dialect}") String dialect) {
+ LocalContainerEntityManagerFactoryBean x = new LocalContainerEntityManagerFactoryBean();
+ x.setDataSource(dataSource);
+ x.setJpaPropertyMap(createJpaMap(hbm2ddl, showSql, dialect));
+ x.setPackagesToScan(Article.class.getPackage().getName());
+ HibernatePersistence persistenceProvider = new HibernatePersistence();
+ x.setPersistenceProvider(persistenceProvider);
+ return x;
+ }
+
+ public static Map<String, Object> createJpaMap(String hbm2ddl, boolean showSql, String dialect) {
+ Map<String, Object> map = new HashMap<>();
+ map.put(HBM2DDL_AUTO, hbm2ddl);
+ map.put(FORMAT_SQL, showSql);
+ map.put(SHOW_SQL, showSql);
+ map.put(USE_SQL_COMMENTS, showSql);
+ map.put(GENERATE_STATISTICS, true);
+ map.put(NAMING_STRATEGY, ImprovedNamingStrategy.class.getName());
+
+ map.put(DEFAULT_CACHE_CONCURRENCY_STRATEGY, CacheConcurrencyStrategy.READ_WRITE.toString());
+ map.put(CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());
+// map.put(CACHE_REGION_FACTORY, EhCacheRegionFactory.class.getName());
+ map.put(USE_SECOND_LEVEL_CACHE, false);
+ map.put(USE_QUERY_CACHE, false);
+// map.put(SHARED_CACHE_MODE, SharedCacheMode.ENABLE_SELECTIVE.toString());
+
+ map.put(DIALECT, dialect);
+ map.put("hibernate.temp.use_jdbc_metadata_defaults", "false");
+
+ return map;
+ }
+
+ @Bean
+ public SessionFactory sessionFactory(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
+ return ((HibernateEntityManagerFactory) entityManagerFactory.nativeEntityManagerFactory).getSessionFactory();
+ }
+
+ @Bean
+ public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
+ return new JpaTransactionManager(entityManagerFactory);
+ }
+
+ @Bean
+ public TransactionTemplate transactionTemplate(PlatformTransactionManager platformTransactionManager) {
+ return new TransactionTemplate(platformTransactionManager);
+ }
+}
diff --git a/src/main/resources/applicationContext.xml b/src/main/resources/applicationContext.xml
new file mode 100755
index 0000000..9856a0b
--- /dev/null
+++ b/src/main/resources/applicationContext.xml
@@ -0,0 +1,22 @@
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://www.springframework.org/schema/beans"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:jdbc="http://www.springframework.org/schema/jdbc"
+ xmlns:jee="http://www.springframework.org/schema/jee"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:jpa="http://www.springframework.org/schema/data/jpa"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
+ http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
+ http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
+ http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
+ http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
+
+ <context:annotation-config/>
+ <bean class="io.trygvis.spring.Config"/>
+
+</beans>
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100755
index 0000000..038a2f1
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,28 @@
+<configuration debug="false">
+
+ <logger name="io.trygvis" level="DEBUG"/>
+<!--
+ <logger name="org.springframework" level="INFO"/>
+-->
+ <logger name="org.springframework" level="INFO"/>
+ <logger name="org.springframework.scheduling" level="DEBUG"/>
+ <logger name="org.springframework.jdbc.core.JdbcTemplate" level="DEBUG"/>
+ <logger name="org.hibernate" level="DEBUG"/>
+ <logger name="org.quartz" level="DEBUG"/>
+<!--
+ <logger name="org" level="INFO"/>
+ <logger name="net" level="INFO"/>
+ <logger name="com" level="INFO"/>
+-->
+ <logger name="com.jolbox" level="DEBUG"/>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT"/>
+ </root>
+</configuration>
ef='#n1627'>1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657