diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..76497e9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,7 @@
+language: java
+sudo: false # faster builds
+
+script: "mvn cobertura:cobertura"
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..7d2c190
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,166 @@
+# act-ebean-java7 CHANGE LOG
+
+1.8.1
+* Allow app to define customised ebean IdGenerator #22
+
+1.8.0
+* update to act-1.8.29
+* update EbeanDao - add `processLikeValue` method
+
+1.7.9 - 30/Sep/2019
+* update to act-1.8.28
+* update to act-sql-common-1.5.1
+
+1.7.8 - 03/Jul/2019
+* update to act-1.8.25
+* update to act-sql-common-1.5.0
+
+1.7.7 - 16/Jun/2019
+* update to act-1.8.23
+* update to act-sql-common-1.4.6
+
+1.7.6 - 20/Apr/2019
+* Update to act-1.8.20
+
+1.7.5 - 20/Nov/2018
+* Catch up Ebean2 fix on GH28
+* update act to 1.8.12
+
+1.7.4 - 04/Nov/2018
+* update to act-1.8.9
+* update to act-sql-common to 1.4.4
+
+1.7.3 - 30/Oct/2018
+* update to act-1.8.8
+* update to act-sql-common 1.4.3
+
+1.7.2 - 19/Jun/2018
+* update to act-1.8.8-RC10
+* update act-sql-common to 1.4.2
+
+1.7.1 - 7/Jun/2018
+* update act to 1.8.8-RC9
+* update act-sql-common to 1.4.1
+* catch up act-ebean-1.7.1 updates
+
+1.7.0 - 29/May/2018
+* update act to 1.8.8-RC8
+* update act-sql-common to 1.4.0
+
+1.6.2 - 19/May/2018
+* catch up act-ebean 1.6.5 changes
+
+1.6.1 - 14/May/2018
+* catch act-ebean 1.6.4 changes
+
+1.6.0 - 13/May/2018
+* update act to 1.8.8-RC4
+* Disable Ebean classpath search #21
+* Register global mapping filter to avoid copying ebean enhanced fields #20
+
+
+1.5.3 - 02/Apr/2018
+* update act to 1.8.5
+* update act-sql-common to 1.3.3
+
+1.5.2 - 25/Mar/2018
+* rename to act-ebean-java7
+* update act to 1.8.2
+* update act-sql-common to 1.3.2
+
+------------------------------------
+
+Previous named act-ebean
+
+1.5.1 - 11/Mar/2018
+* update to act-1.8.1
+* update to act-sql-common-1.3.1
+
+1.5.0 - 4/Mar/2018
+* update to act-1.8.0
+* catch ebean2 change: Support act timestamp annotation #19
+
+1.4.0 - 19/Feb/2018
+* update to act-1.7.0
+* update to act-sql-common-1.3.0
+
+1.3.2 - 23/Jan/2018
+* update to act-1.6.5
+* update act-sql-common to 1.2.1
+
+1.3.1 - 11/Jan/2018
+* update to act-1.6.2
+* add `@BindOn` annotation to `EbeanConfigLoaded` event class to allow early bind of event listeners
+
+1.3.0 - 28/Dec/2017
+* update to act-1.6.0
+
+1.2.3
+* update to act-1.4.11, act-sql-common-1.1.1
+* apply oslg-bootstrap version mechanism
+* improve maven build process
+
+1.2.2
+* catch up to sql-common-1.1.1
+
+1.2.1
+* catch up to ebean2-1.1.1
+
+1.2.0
+* catch up to act-1.4.0
+* catch up to act-sql-common to 1.1.0
+
+1.1.5
+- NPE when no third party datasource configured #16
+- update sql-common to 1.0.2
+
+1.1.4
+- update to act-sql-common-1.0.1
+- Ebean Agent loaded twice if there are two ebean db services #14
+- The datasource created in sql-common not used when creating ebean server #15
+
+1.1.3
+- It should use ebean's naming convention by default #13
+
+1.1.2
+- Migrate to act-1.1.0 new DB architecture #12
+
+1.1.1
+- HikariDataSourceProvider.confKeyMapping error #10
+- DruidDataSourceProvider.confKeyMapping() error #11
+
+1.1.0
+- Support plugin different datasource solution #9
+- change mysql jdbc driver class name #8
+- Support Druid database #6
+
+1.0.5
+- It reports XXX table not found when start app in dev mode #7
+
+1.0.4
+- take out version range from pom.xml. See https://issues.apache.org/jira/browse/MNG-3092
+
+1.0.3
+- version number of mistake
+
+1.0.2
+- use HikariCP for connection pool #4
+- Make it easy to do low level JDBC logic #5
+
+1.0.1
+- EbeanDao.drop() method cause JdbcSQLException #1
+- EbeanInjectionListener not effect on User defined Dao #3
+
+1.0.0
+- the first formal release
+
+0.7.0 - update act to 0.7.0
+0.6.0 - update act to 0.6.0
+0.5.0 - upgrade to act 0.5.0 (to reserve 0.4.0 for techempower test)
+0.4.0 - upgrade to act 0.4.0
+0.3.1 - upgrade to act 0.3.1
+0.3.0 - upgrade to act 0.3.0
+0.2.0 - upgrade to act 0.2.0
+ - upgrade to ebean-8
+0.1.2 - upgrade to act 0.1.2
+0.1.1 - baseline version
diff --git a/README.md b/README.md
index 782b4dd..c1596e7 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,35 @@
# act-ebean
-Ebean plugin for ACT Framework
+[](http://www.apache.org/licenses/LICENSE-2.0.html)
+[](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22act-ebean%22)
+[](https://travis-ci.org/actframework/act-ebean)
+[](https://codecov.io/gh/actframework/act-ebean)
+[](http://www.javadoc.io/doc/org.actframework/act-ebean)
+
+
+Ebean plugin for ACT Framework.
+
+## act-ebean vs act-ebean2
+
+* act-ebean: support JDK7 and JDK8
+* act-ebean2: uses latest ebean version but can only run on JDK8
+
+## Versions
+
+| ActFramework | act-ebean |
+| ------------ | -------- |
+| 1.0.x | 1.0.x, 1.1.0, 1.1.1 |
+| 1.1.x | 1.1.2+ |
+
+## Configuration
+
+For configuration items, please refer to [act-sql-common](https://github.com/actframework/act-sql-common)
+
+If application needs to manipulate the loaded configuration before `EbeanServer` is created, try add the following method in any Class:
+
+```java
+@OnEvent(beforeAppStart = true)
+public static void configureEbean(ServerConfig config) {
+ // do whatever required on ebean's ServerConfig
+}
+```
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 0000000..5bd34d5
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,209 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
old mode 100755
new mode 100644
index e560f00..f5c1956
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,6 @@
-
4.0.0
- org.actframework
- act-ebean
+ act-ebean-java7
jar
- 1.0.5-SNAPSHOT
+ 1.8.1-SNAPSHOT
ACT Ebean
- The Ebean Plugin for Actframework SQL database access
+ Provides SQL database access through Ebean ORM library (java 7+)
http://actframework.org/plugin/ebean
+ 2015
+
+
+ ActFramework
+ http://actframework.org
+
+
+
+ org.actframework
+ parent
+ 1.8.29
+
- UTF-8
- UTF-8
- git@github.com:actframework/act-ebean.git
- 1.0.5
+ git@github.com:actframework/act-ebean.git
+
8.8.1
8.1.1
2.1.2
- 2.7.0
- 2.6.1
-
-
- org.sonatype.oss
- oss-parent
- 7
-
+ 1.6.0
+
+
- scm:git:${git.url}
- scm:git:${git.url}
- ${git.url}
+ scm:git:${scm.url}
+ scm:git:${scm.url}
+ ${scm.url}
-
-
- The Apache Software License, Version 2.0
- http://www.apache.org/licenses/LICENSE-2.0.txt
- repo
-
-
-
-
-
-
- src/main/resources
- true
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.3
-
- 1.7
- 1.7
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 2.1.2
-
- true
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.9
-
- src/etc/javadoc.css
-
-
-
-
- gen-javadoc
- prepare-package
-
- javadoc
-
-
-
- attach-javadocs
-
- jar
-
-
-
-
-
-
-
-
-
- junit
- junit
- 4.10
- test
-
-
-
- org.mockito
- mockito-core
- ${mockito-core.version}
- test
-
-
org.avaje.ebean
ebean
@@ -177,72 +77,17 @@
org.actframework
- act
- ${act.version}
- provided
+ act-sql-common
+ ${act-sql-common.version}
- com.zaxxer
- HikariCP
- ${HikariCP.version}
- compile
+ org.actframework
+ act
+ ${act.version}
+ provided
-
-
- dist
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 2.2
-
-
- ${basedir}/assembly-dist.xml
-
- gnu
-
-
-
- make-assembly
- package
-
- single
-
-
-
- ${basedir}/assembly-dist.xml
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
-
-
- attach-sources
-
- jar
-
-
-
-
-
- com.mycila.maven-license-plugin
- maven-license-plugin
-
-
-
-
-
-
-
-
-
diff --git a/src/etc/javadoc.css b/src/etc/javadoc.css
new file mode 100644
index 0000000..e951d01
--- /dev/null
+++ b/src/etc/javadoc.css
@@ -0,0 +1,622 @@
+@import url(highlight.css);
+
+body {
+ background-color:#222222;
+ color:#D2DECA;
+ font-family:'Roboto', 'San Francisco Text', 'Noto Sans', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+ font-size:16px;
+ margin:0;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#999;
+}
+a:hover, a:focus {
+ text-decoration:underline;
+}
+a:active {
+ text-decoration:none;
+ color:#999;
+}
+a[name] {
+ color:#D2DECA;
+}
+a[name]:hover {
+ text-decoration:none;
+ color:#D2DECA;
+}
+/*[MOD]
+pre {
+ font-family:'Roboto Mono', 'Envy Code R', Consolas, Menlo, Monaco,monospace;
+ font-size:14px;
+}*/
+h1 {
+ font-size:20px;
+}
+h2 {
+ font-size:18px;
+}
+h3 {
+ font-size:16px;
+ font-style:italic;
+}
+h4 {
+ font-size:13px;
+}
+h5 {
+ font-size:12px;
+}
+h6 {
+ font-size:11px;
+}
+ul {
+ list-style-type:disc;
+}
+
+code, tt {
+ font-family:'Roboto Mono', 'Envy Code R', Consolas, Menlo, Monaco,monospace;
+ font-size:14px;
+ padding-top:4px;
+ margin-top:8px;
+ line-height:1.4em;
+}
+dt code {
+ font-family:'Roboto Mono', 'Envy Code R', Consolas, Menlo, Monaco,monospace;
+ font-size:14px;
+ padding-top:4px;
+}
+table tr td dt code {
+ font-family:'Roboto Mono', 'Envy Code R', Consolas, Menlo, Monaco,monospace;
+ font-size:14px;
+ vertical-align:top;
+ padding-top:4px;
+}
+sup {
+ font-size:8px;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:.8em;
+ z-index:200;
+ margin-top:-7px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#222222;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#999;
+}
+.tab {
+ background-color:#004F66;
+ color:#D0D0D0;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+ background-color:#818487;
+ color:#080707;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:11px;
+ margin:0;
+}
+.topNav {
+ background-color:#818487;
+ color:#222222;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.bottomNav {
+ margin-top:10px;
+ background-color:#818487;
+ color:#222222;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav {
+ background-color:#47494C;
+ float:left;
+ width:100%;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+ text-transform:uppercase;/*???*/
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding: 5px 6px;
+ text-transform:uppercase;/*???*/
+}
+ul.subNavList li{
+ list-style:none;
+ float:left;
+ font-size:90%;/*???*/
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#222222;
+ text-decoration:none;
+ text-transform:uppercase;/*???*/
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#999;
+ text-transform:uppercase;/*???*/
+}
+.navBarCell1Rev {
+ background-color:#C2C2C2;
+ color:#253441;
+ margin: auto 5px;
+}
+.skipNav {
+ position:absolute;
+ top:auto;
+ left:-9999px;
+ overflow:hidden;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexHeader {
+ margin:10px;
+ position:relative;
+}
+.indexHeader span{
+ margin-right:15px;
+}
+.indexHeader h1 {
+ font-size:13px;
+}
+.title {
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 15px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:13px;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#47494C;
+ border:none;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#47494C;
+ border:none;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:10px 0 10px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:14px;
+}
+.indexContainer h2 {
+ font-size:15px;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+ padding-top:2px;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:14px;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#e4e4e4;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:5px 0 10px 0px;
+ font-size:14px;
+ font-family:'DejaVu Sans Mono',monospace;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:15px;
+ line-height:1.4;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #545454;
+ background-color:#282828;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#222222;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {
+ width:100%;
+ border-left:1px solid #333;
+ border-right:1px solid #333;
+ border-bottom:1px solid #333;
+}
+.overviewSummary, .memberSummary {
+ padding:0px;
+}
+.overviewSummary caption, .memberSummary caption, .typeSummary caption,
+.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#253441;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ padding-top:10px;
+ padding-left:1px;
+ margin:0px;
+ white-space:pre;
+}
+.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
+.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,
+.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
+.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
+.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
+.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,
+.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
+.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {
+ color:#222222;
+}
+.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
+.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ padding-bottom:7px;
+ display:inline-block;
+ float:left;
+ background-color:#C2C2C2;
+ border: none;
+ height:16px;
+}
+.memberSummary caption span.activeTableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#C2C2C2;
+ height:16px;
+}
+.memberSummary caption span.tableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#818487;
+ height:16px;
+}
+.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {
+ padding-top:0px;
+ padding-left:0px;
+ padding-right:0px;
+ background-image:none;
+ float:none;
+ display:inline;
+}
+.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
+.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {
+ display:none;
+ width:5px;
+ position:relative;
+ float:left;
+ background-color:#C2C2C2;
+}
+.memberSummary .activeTableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ float:left;
+ background-color:#C2C2C2;
+}
+.memberSummary .tableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ background-color:#818487;
+ float:left;
+
+}
+.overviewSummary td, .memberSummary td, .typeSummary td,
+.useSummary td, .constantsSummary td, .deprecatedSummary td {
+ text-align:left;
+ padding:0px 0px 12px 10px;
+ width:100%;
+}
+th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,
+td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{
+ vertical-align:top;
+ padding-right:0px;
+ padding-top:8px;
+ padding-bottom:3px;
+}
+th.colFirst, th.colLast, th.colOne, .constantsSummary th {
+ background:#47494C;
+ text-align:left;
+ padding:8px 3px 3px 7px;
+}
+td.colFirst, th.colFirst {
+ white-space:nowrap;
+ font-size:13px;
+}
+td.colLast, th.colLast {
+ font-size:13px;
+}
+td.colOne, th.colOne {
+ font-size:13px;
+}
+.overviewSummary td.colFirst, .overviewSummary th.colFirst,
+.overviewSummary td.colOne, .overviewSummary th.colOne,
+.memberSummary td.colFirst, .memberSummary th.colFirst,
+.memberSummary td.colOne, .memberSummary th.colOne,
+.typeSummary td.colFirst{
+ width:25%;
+ vertical-align:top;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+ font-weight:bold;
+}
+.tableSubHeadingColor {
+ background-color:#2F3131;
+}
+.altColor {
+ background-color:#222222;
+}
+.rowColor {
+ background-color:#2F3131;
+}
+/*
+Content styles
+*/
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ font-style:normal;
+}
+
+div.block {
+ font-size:16px;
+ font-family:'Roboto', 'San Francisco Text', 'Noto Sans', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
+}
+
+td.colLast div {
+ padding-top:0px;
+}
+
+
+td.colLast a {
+ padding-bottom:3px;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:10px;
+}
+.block {
+ display:block;
+ margin:3px 10px 2px 0px;
+ color:#E9E9e9;
+}
+.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,
+.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,
+.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {
+ font-weight:bold;
+}
+.deprecationComment, .emphasizedPhrase, .interfaceName {
+ font-style:italic;
+}
+
+div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,
+div.block div.block span.interfaceName {
+ font-style:normal;
+}
+
+/* code block tweaks */
+code, tt {
+ font-size: 14px;
+}
+pre {
+ /* inspired by GitHub */
+ padding: 0 5px;
+ border: solid 1px #888;
+ background: #888;
+ border-radius: none;
+}
+pre code {
+ background: none;
+}
+li.blockList > pre {
+ font-size: 16px;
+ padding: 0;
+ margin: 0;
+ background: 0;
+ border: 0;
+}
+div.summary code {
+ background: none;
+ border: 0;
+ padding: 0;
+}
+
+/* @todo tag */
+div.todo {
+ display: block;
+ margin: 1em;
+ border: solid 1px black;
+ border-radius: 3px;
+}
+div.todoTitle {
+ display: block;
+ background: #f6f30d;
+ padding: 5px;
+ border-bottom: solid 1px black;
+}
+span.todoTitle {
+ font-weight: bold;
+}
+span.todoCounter {
+ float: right;
+ font-size: .8em;
+}
+div.todoText {
+ display: block;
+ padding: 5px;
+}
+
+pre .comment, pre .annotation, pre .template_comment, pre .diff .header, pre .chunk, pre .markdown .blockquote {
+ color: #333
+}
\ No newline at end of file
diff --git a/src/main/java/act/db/ebean/EbeanAgentLoader.java b/src/main/java/act/db/ebean/EbeanAgentLoader.java
index 1d0eade..1894cd8 100644
--- a/src/main/java/act/db/ebean/EbeanAgentLoader.java
+++ b/src/main/java/act/db/ebean/EbeanAgentLoader.java
@@ -1,38 +1,55 @@
package act.db.ebean;
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2017 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import act.Act;
+import act.app.event.SysEventId;
+import act.sys.Env;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import com.sun.tools.attach.spi.AttachProvider;
import org.avaje.agentloader.AgentLoader;
+import org.osgl.logging.LogManager;
+import org.osgl.logging.Logger;
+import org.osgl.util.S;
import sun.tools.attach.BsdVirtualMachine;
import sun.tools.attach.LinuxVirtualMachine;
import sun.tools.attach.SolarisVirtualMachine;
import sun.tools.attach.WindowsVirtualMachine;
-import java.io.File;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
+import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
-import java.util.logging.Logger;
public class EbeanAgentLoader extends AgentLoader {
- private static final Logger log = Logger.getLogger(AgentLoader.class.getName());
+ private static final Logger LOGGER = LogManager.get(EbeanAgentLoader.class.getName());
private static final List loaded = new ArrayList();
- private static final String discoverPid() {
- String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
- int p = nameOfRunningVM.indexOf('@');
- return nameOfRunningVM.substring(0, p);
- }
-
private static final AttachProvider ATTACH_PROVIDER = new AttachProvider() {
@Override
public String name() {
@@ -66,11 +83,9 @@ public static void loadAgent(String jarFilePath) {
* Load an agent providing the full file path with parameters.
*/
public static void loadAgent(String jarFilePath, String params) {
-
- log.info("dynamically loading javaagent for " + jarFilePath);
try {
- String pid = discoverPid();
+ String pid = Env.PID.get();
VirtualMachine vm;
if (AttachProvider.providers().isEmpty()) {
@@ -79,7 +94,24 @@ public static void loadAgent(String jarFilePath, String params) {
vm = VirtualMachine.attach(pid);
}
- vm.loadAgent(jarFilePath, params);
+ final PrintStream ps = System.out;
+ try {
+ System.setOut(new PrintStream(new FileOutputStream(".ebean_agent.log")));
+ vm.loadAgent(jarFilePath, params);
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("javaagent loaded: " + jarFilePath);
+ }
+ } finally {
+ // ensure ebean2 EnhanceContext logout set to dump output
+ Act.jobManager().on(SysEventId.CLASS_LOADER_INITIALIZED,
+ S.buffer("EbeanAgentLoader - clean up for ").append(jarFilePath).toString(),
+ new Runnable() {
+ @Override
+ public void run() {
+ System.setOut(ps);
+ }
+ });
+ }
vm.detach();
} catch (Exception e) {
@@ -98,8 +130,10 @@ public static void loadAgentFromClasspath(String agentName) {
* Load the agent from the classpath using its name and passing params.
*/
public synchronized static boolean loadAgentFromClasspath(String agentName, String params) {
-
if (loaded.contains(agentName)) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(S.concat("agent already loaded: ", agentName));
+ }
// the agent is already loaded
return true;
}
@@ -118,14 +152,20 @@ public synchronized static boolean loadAgentFromClasspath(String agentName, Stri
if (fullName.startsWith("/") && isWindows()) {
fullName = fullName.substring(1);
}
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace(S.concat("loading agent: ", fullName));
+ }
loadAgent(fullName, params);
- loaded.add(fullName);
+ loaded.add(agentName);
return true;
}
}
}
// Agent not found and not loaded
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("agent not found");
+ }
return false;
} catch (URISyntaxException use) {
diff --git a/src/main/java/act/db/ebean/EbeanConfigLoaded.java b/src/main/java/act/db/ebean/EbeanConfigLoaded.java
new file mode 100644
index 0000000..24d36c2
--- /dev/null
+++ b/src/main/java/act/db/ebean/EbeanConfigLoaded.java
@@ -0,0 +1,41 @@
+package act.db.ebean;
+
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2017 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static act.app.event.SysEventId.DEPENDENCY_INJECTOR_PROVISIONED;
+
+import act.event.ActEvent;
+import act.event.BindOn;
+import com.avaje.ebean.config.ServerConfig;
+
+/**
+ * The event get triggered when {@link ServerConfig} is loaded and
+ * before the {@link com.avaje.ebean.EbeanServer} is created.
+ *
+ * Application can use this event to do further configuration on
+ * {@link ServerConfig}
+ */
+@BindOn(DEPENDENCY_INJECTOR_PROVISIONED)
+public class EbeanConfigLoaded extends ActEvent {
+ public EbeanConfigLoaded(ServerConfig source) {
+ super(source);
+ }
+}
diff --git a/src/main/java/act/db/ebean/EbeanConfigurator.java b/src/main/java/act/db/ebean/EbeanConfigurator.java
new file mode 100644
index 0000000..d7b8ef3
--- /dev/null
+++ b/src/main/java/act/db/ebean/EbeanConfigurator.java
@@ -0,0 +1,36 @@
+package act.db.ebean;
+
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2020 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+
+import com.avaje.ebean.config.ServerConfig;
+
+/**
+ * Application to implement this interface to do further
+ * configuration to {@link ServerConfig Ebean ServerConfig}.
+ */
+public interface EbeanConfigurator {
+ /**
+ * Configure the Ebean {@link ServerConfig}.
+ * @param ebeanConfig the Ebean config instance
+ */
+ void configure(ServerConfig ebeanConfig);
+}
diff --git a/src/main/java/act/db/ebean/EbeanConfiguratorManager.java b/src/main/java/act/db/ebean/EbeanConfiguratorManager.java
new file mode 100644
index 0000000..922aedb
--- /dev/null
+++ b/src/main/java/act/db/ebean/EbeanConfiguratorManager.java
@@ -0,0 +1,39 @@
+package act.db.ebean;
+
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2020 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import com.avaje.ebean.config.ServerConfig;
+
+import javax.inject.Inject;
+import java.util.List;
+
+public class EbeanConfiguratorManager {
+
+ @Inject
+ private List configurators;
+
+ void callConfigurators(ServerConfig config) {
+ for (EbeanConfigurator configurator : configurators) {
+ configurator.configure(config);
+ }
+ }
+
+}
diff --git a/src/main/java/act/db/ebean/EbeanDao.java b/src/main/java/act/db/ebean/EbeanDao.java
index 92acf60..9e0ce5c 100644
--- a/src/main/java/act/db/ebean/EbeanDao.java
+++ b/src/main/java/act/db/ebean/EbeanDao.java
@@ -1,53 +1,71 @@
package act.db.ebean;
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2017 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static act.Act.app;
+
import act.app.DbServiceManager;
-import act.db.DB;
-import act.db.DaoBase;
-import act.db.DbService;
+import act.db.*;
import act.db.Model;
-import act.inject.param.NoBind;
+import act.db.sql.tx.TxContext;
import act.util.General;
+import act.util.Stateless;
import com.avaje.ebean.*;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import org.osgl.$;
import org.osgl.logging.L;
import org.osgl.logging.Logger;
-import org.osgl.util.C;
-import org.osgl.util.E;
-import org.osgl.util.S;
+import org.osgl.util.*;
-import javax.persistence.Id;
-import javax.sql.DataSource;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import static act.Act.app;
+import java.util.*;
+import javax.persistence.Id;
+import javax.sql.DataSource;
@General
-@NoBind
public class EbeanDao extends DaoBase> {
private static final Logger logger = L.get(EbeanDao.class);
- private volatile EbeanServer ebean;
- private volatile DataSource ds;
- private String tableName;
- private Field idField = null;
- private List queryIterators = C.newList();
+ @Stateless private volatile EbeanServer ebean;
+ @Stateless private volatile EbeanServer ebeanReadOnly;
+ @Stateless private volatile EbeanService dbSvc;
+ @Stateless private volatile DataSource ds;
+ @Stateless private volatile DataSource dsReadOnly;
+ @Stateless private String tableName;
+ @Stateless private Field idField = null;
+ @Stateless private List queryIterators = C.newList();
EbeanDao(EbeanService service) {
init(modelType());
- this.ebean(service.ebean());
+ this.dbService(service);
}
EbeanDao(Class idType, Class modelType, EbeanService service) {
super(idType, modelType);
init(modelType);
- this.ebean(service.ebean());
- this.ds = service.ds();
+ this.dbService(service);
+ this.ds = service.dataSource();
+ this.dsReadOnly = service.dataSourceReadOnly();
}
public EbeanDao(Class id_type, Class modelType) {
@@ -59,9 +77,14 @@ public EbeanDao() {
init(modelType());
}
- public void ebean(EbeanServer ebean) {
- this.ebean = $.notNull(ebean);
- this.tableName = ((SpiEbeanServer) ebean).getBeanDescriptor(modelType()).getBaseTable();
+ public void ebean(EbeanServer ebean, boolean readonly) {
+ setEbean($.requireNotNull(ebean), readonly);
+ }
+
+ public void dbService(EbeanService service) {
+ this.dbSvc = service;
+ this.ebean(service.ebean(true), true);
+ this.ebean(service.ebean(false), false);
}
public void modelType(Class> type) {
@@ -92,9 +115,15 @@ private void init(Class modelType) {
break;
}
}
- if (null != ebean) {
- this.tableName = ((SpiEbeanServer) ebean).getBeanDescriptor(modelType()).getBaseTable();
+ }
+
+ private void setEbean(EbeanServer ebean, boolean readonly) {
+ if (readonly) {
+ this.ebeanReadOnly = ebean;
+ return;
}
+ this.ebean = ebean;
+ this.tableName = ((SpiEbeanServer) ebean).getBeanDescriptor(modelType()).getBaseTable();
}
private EbeanService getService(String dbId, DbServiceManager mgr) {
@@ -104,20 +133,27 @@ private EbeanService getService(String dbId, DbServiceManager mgr) {
return $.cast(svc);
}
- public EbeanServer ebean() {
- if (null != ebean) {
+ private EbeanServer ebean_(boolean defaultReadOnly) {
+ boolean ctxReadOnly = TxContext.readOnly(defaultReadOnly);
+ E.illegalStateIf(!defaultReadOnly && ctxReadOnly, "Cannot do write operation within readonly transaction");
+ return ebean(ctxReadOnly);
+ }
+
+ public EbeanServer ebean(boolean readonly) {
+ dbSvc.beginTxIfRequired(null);
+ if (!readonly && null != ebean) {
return ebean;
}
+ if (readonly && null != ebeanReadOnly) {
+ return ebeanReadOnly;
+ }
synchronized (this) {
- if (null == ebean) {
- DB db = modelType().getAnnotation(DB.class);
- String dbId = null == db ? DbServiceManager.DEFAULT : db.value();
- EbeanService dbService = getService(dbId, app().dbServiceManager());
- E.NPE(dbService);
- ebean = dbService.ebean();
- }
+ DB db = modelType().getAnnotation(DB.class);
+ String dbId = null == db ? DbServiceManager.DEFAULT : db.value();
+ EbeanService dbService = getService(dbId, app().dbServiceManager());
+ dbService(dbService);
+ return readonly ? ebeanReadOnly : ebean;
}
- return ebean;
}
public DataSource ds() {
@@ -130,7 +166,7 @@ public DataSource ds() {
String dbId = null == db ? DbServiceManager.DEFAULT : db.value();
EbeanService dbService = getService(dbId, app().dbServiceManager());
E.NPE(dbService);
- ds = dbService.ds();
+ ds = dbService.dataSource();
}
}
return ds;
@@ -142,7 +178,17 @@ void registerQueryIterator(QueryIterator i) {
@Override
public MODEL_TYPE findById(ID_TYPE id) {
- return ebean().find(modelType(), id);
+ return ebean_(true).find(modelType(), id);
+ }
+
+ @Override
+ public MODEL_TYPE findLatest() {
+ throw E.unsupport();
+ }
+
+ @Override
+ public MODEL_TYPE findLastModified() {
+ throw E.unsupport();
}
@Override
@@ -176,7 +222,7 @@ public List findAllAsList() {
@Override
public MODEL_TYPE reload(MODEL_TYPE entity) {
- ebean().refresh(entity);
+ ebean_(true).refresh(entity);
return entity;
}
@@ -208,12 +254,12 @@ public long countBy(String fields, Object... values) throws IllegalArgumentExcep
@Override
public MODEL_TYPE save(MODEL_TYPE entity) {
- ebean().save(entity);
+ ebean_(false).save(entity);
return entity;
}
public MODEL_TYPE save(Transaction tx, MODEL_TYPE entity) {
- ebean().save(entity, tx);
+ ebean_(false).save(entity, tx);
return entity;
}
@@ -223,61 +269,50 @@ public List save(Iterable iterable) {
if (list.isEmpty()) {
return list;
}
- Transaction transaction = ebean().createTransaction(TxIsolation.READ_COMMITED);
- transaction.setBatchMode(true);
- transaction.setBatchSize(list.size());
- try {
- ebean().saveAll(list);
- transaction.commit();
- } catch (RuntimeException e) {
- transaction.rollback();
- throw e;
- } finally {
- transaction.end();
- }
+ ebean_(false).saveAll(list);
return list;
}
public List save(Transaction tx, Iterable iterable) {
List list = C.list(iterable);
- ebean().saveAll(list, tx);
+ ebean_(false).saveAll(list, tx);
return list;
}
@Override
public void save(MODEL_TYPE entity, String fields, Object... values) throws IllegalArgumentException {
- ebean().update(entity);
+ ebean_(false).update(entity);
}
public void save(Transaction tx, MODEL_TYPE entity, String fields, Object... values) throws IllegalArgumentException {
- ebean().update(entity, tx);
+ ebean_(false).update(entity, tx);
}
@Override
public void delete(MODEL_TYPE entity) {
- ebean().delete(entity);
+ ebean_(false).delete(entity);
}
public void delete(Transaction tx, MODEL_TYPE entity) {
- ebean().delete(entity, tx);
+ ebean_(false).delete(entity, tx);
}
@Override
public void delete(EbeanQuery query) {
- ebean().delete(query.rawQuery(), null);
+ ebean_(false).delete(query.rawQuery(), null);
}
public void delete(Transaction tx, EbeanQuery query) {
- ebean().delete(query.rawQuery(), tx);
+ ebean_(false).delete(query.rawQuery(), tx);
}
@Override
public void deleteById(ID_TYPE id) {
- ebean().delete(modelType(), id);
+ ebean_(false).delete(modelType(), id);
}
public void deleteById(Transaction tx, ID_TYPE id) {
- ebean().delete(modelType(), id, tx);
+ ebean_(false).delete(modelType(), id, tx);
}
@Override
@@ -301,13 +336,13 @@ public void deleteAll(Transaction tx) {
@Override
public void drop() {
String sql = "DELETE from " + tableName;
- SqlUpdate sqlUpdate = ebean().createSqlUpdate(sql);
- ebean().execute(sqlUpdate);
+ SqlUpdate sqlUpdate = ebean_(false).createSqlUpdate(sql);
+ ebean_(false).execute(sqlUpdate);
}
@Override
public EbeanQuery q() {
- return new EbeanQuery(this, modelType());
+ return new EbeanQuery<>(this, modelType());
}
@Override
@@ -315,6 +350,10 @@ public EbeanQuery createQuery() {
return q();
}
+ boolean ebeanServerProvided() {
+ return null != ebean;
+ }
+
private enum R2 {
betweenProperties() {
@Override
@@ -502,10 +541,25 @@ private void buildWhere(ExpressionList where, String key, Object val
where.eq(sa[0], val);
break;
case 2:
- R1.valueOf(sa[1]).applyTo(where, sa[0], val);
+ String op = sa[1];
+ if ("!=".equalsIgnoreCase(op)) {
+ op = "ne";
+ } else if ("==".equalsIgnoreCase(op)) {
+ op = "eq";
+ } else if (">".equalsIgnoreCase(op)) {
+ op = "gt";
+ } else if (">=".equals(op)) {
+ op = "ge";
+ } else if ("<".equals(op)) {
+ op = "lt";
+ } else if ("<=".equals(op)) {
+ op = "le";
+ }
+ R1.valueOf(op).applyTo(where, sa[0], val);
break;
case 3:
R2.valueOf(sa[2]).applyTo(where, sa[0], sa[1], val);
+ break;
default:
throw E.unexpected("Unknown where expression: %s", key);
}
@@ -529,4 +583,9 @@ public EbeanQuery q(String keys, Object... values) {
public EbeanQuery createQuery(String s, Object... objects) {
return q(s, objects);
}
+
+ @Override
+ public Object processLikeValue(String v) {
+ return v.contains("%") ? v : "%" + v + "%";
+ }
}
diff --git a/src/main/java/act/db/ebean/EbeanDaoInjectionListener.java b/src/main/java/act/db/ebean/EbeanDaoInjectionListener.java
index e246255..9cff1b4 100644
--- a/src/main/java/act/db/ebean/EbeanDaoInjectionListener.java
+++ b/src/main/java/act/db/ebean/EbeanDaoInjectionListener.java
@@ -1,13 +1,37 @@
package act.db.ebean;
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2017 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import act.Act;
import act.app.App;
+import act.app.event.SysEventId;
import act.db.DbService;
import act.db.di.DaoInjectionListenerBase;
+import act.event.SysEventListenerBase;
import org.osgl.$;
import org.osgl.inject.BeanSpec;
import org.osgl.util.Generics;
import java.lang.reflect.Type;
+import java.util.EventObject;
import java.util.List;
public class EbeanDaoInjectionListener extends DaoInjectionListenerBase {
@@ -19,6 +43,10 @@ public Class[] listenTo() {
@Override
public void onInjection(Object injectee, BeanSpec spec) {
+ final EbeanDao dao = $.cast(injectee);
+ if (dao.ebeanServerProvided()) {
+ return;
+ }
List typeParameters = spec.typeParams();
if (typeParameters.isEmpty()) {
typeParameters = Generics.typeParamImplementations(spec.rawType(), EbeanDao.class);
@@ -27,13 +55,17 @@ public void onInjection(Object injectee, BeanSpec spec) {
logger.warn("No type parameter information provided");
return;
}
- $.T2 resolved = resolve(typeParameters);
+ final $.T2 resolved = resolve(typeParameters);
DbService dbService = App.instance().dbServiceManager().dbService(resolved._2);
if (dbService instanceof EbeanService) {
- EbeanService service = $.cast(dbService);
- EbeanDao dao = $.cast(injectee);
- dao.ebean(service.ebean());
- dao.modelType(resolved._1);
+ final EbeanService service = $.cast(dbService);
+ Act.eventBus().bind(SysEventId.DB_SVC_LOADED, new SysEventListenerBase() {
+ @Override
+ public void on(EventObject eventObject) throws Exception {
+ dao.dbService(service);
+ dao.modelType(resolved._1);
+ }
+ });
}
}
}
diff --git a/src/main/java/act/db/ebean/EbeanModelBase.java b/src/main/java/act/db/ebean/EbeanModelBase.java
index 9c105df..ce61b8b 100644
--- a/src/main/java/act/db/ebean/EbeanModelBase.java
+++ b/src/main/java/act/db/ebean/EbeanModelBase.java
@@ -1,12 +1,31 @@
package act.db.ebean;
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2017 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import act.app.App;
import act.db.Dao;
import act.db.Model;
import org.osgl.$;
import javax.persistence.MappedSuperclass;
-
@MappedSuperclass
public abstract class EbeanModelBase
implements Model {
diff --git a/src/main/java/act/db/ebean/EbeanModule.java b/src/main/java/act/db/ebean/EbeanModule.java
index 827cf6b..4e0e0ca 100644
--- a/src/main/java/act/db/ebean/EbeanModule.java
+++ b/src/main/java/act/db/ebean/EbeanModule.java
@@ -1,5 +1,25 @@
package act.db.ebean;
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2017 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import act.db.ebean.util.EbeanDaoLoader;
import org.osgl.inject.Module;
diff --git a/src/main/java/act/db/ebean/EbeanPlugin.java b/src/main/java/act/db/ebean/EbeanPlugin.java
index 069ab24..916201d 100644
--- a/src/main/java/act/db/ebean/EbeanPlugin.java
+++ b/src/main/java/act/db/ebean/EbeanPlugin.java
@@ -1,19 +1,56 @@
package act.db.ebean;
-import act.ActComponent;
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2017 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import act.app.App;
import act.db.DbPlugin;
import act.db.DbService;
import act.inject.param.ParamValueLoaderService;
+import com.avaje.ebeaninternal.api.ScopeTrans;
+import org.osgl.OsglConfig;
+import osgl.version.Version;
import java.util.Map;
-@ActComponent
public class EbeanPlugin extends DbPlugin {
+
+ public static final Version VERSION = Version.of(EbeanPlugin.class);
+
+ private static final ThreadLocal txHolder = new ThreadLocal<>();
+
+ @Override
+ public void register() {
+ super.register();
+ registerGlobalMappingFilter();
+ }
+
@Override
- public DbService initDbService(String id, App app, Map conf) {
+ public DbService initDbService(String id, App app, Map conf) {
ParamValueLoaderService.waiveFields("_ebean_intercept", "_ebean_identity");
return new EbeanService(id, app, conf);
}
+
+ private void registerGlobalMappingFilter() {
+ OsglConfig.addGlobalMappingFilter("starts:_ebean_");
+ }
+
}
diff --git a/src/main/java/act/db/ebean/EbeanQuery.java b/src/main/java/act/db/ebean/EbeanQuery.java
index 26c0a93..687ec7a 100644
--- a/src/main/java/act/db/ebean/EbeanQuery.java
+++ b/src/main/java/act/db/ebean/EbeanQuery.java
@@ -1,7 +1,28 @@
package act.db.ebean;
+/*-
+ * #%L
+ * ACT Ebean
+ * %%
+ * Copyright (C) 2015 - 2017 ActFramework
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import act.db.Dao;
import com.avaje.ebean.*;
+import org.jetbrains.annotations.Nullable;
import org.osgl.$;
import org.osgl.util.C;
import org.osgl.util.E;
@@ -19,6 +40,7 @@ public class EbeanQuery implements Query, Dao.Query modelType;
Query q;
+ Query qReadOnly;
EbeanDao dao;
public EbeanQuery() {
@@ -34,34 +56,83 @@ public EbeanQuery() {
public EbeanQuery(EbeanDao dao, Class modelType) {
this.modelType = modelType;
- EbeanServer ebean = dao.ebean();
- E.NPE(ebean);
- q = ebean.createQuery(modelType);
+
+ q = dao.ebean(false).createQuery(modelType);
+ qReadOnly = dao.ebean(true).createQuery(modelType);
+ syncEbeanQueries();
+
this.dao = dao;
}
+ private void syncEbeanQueries() {
+
+ _sync("detail");
+
+ q.orderBy();
+ _sync("orderBy");
+
+ q.text();
+ _sync("textExpressions");
+
+ q.where();
+ _sync("whereExpressions");
+
+ q.having();
+ _sync("havingExpressions");
+
+ }
+
+ private void _sync(String property) {
+ $.setProperty(qReadOnly, $.getProperty(q, property), property);
+ }
+
public Query rawQuery() {
return q;
}
@Override
- public Query asOf(Timestamp timestamp) {
- return q.asOf(timestamp);
+ public EbeanQuery asOf(Timestamp timestamp) {
+ q.asOf(timestamp);
+ qReadOnly.asOf(timestamp);
+ return this;
}
@Override
public List> findVersions() {
- return q.findVersions();
+ return qReadOnly.findVersions();
}
@Override
public List> findVersionsBetween(Timestamp timestamp, Timestamp timestamp1) {
- return q.findVersionsBetween(timestamp, timestamp1);
+ return qReadOnly.findVersionsBetween(timestamp, timestamp1);
+ }
+
+ @Override
+ public RawSql getRawSql() {
+ return q.getRawSql();
+ }
+
+ @Override
+ public void findEach(QueryEachConsumer consumer) {
+ qReadOnly.findEach(consumer);
+ }
+
+ @Override
+ public void findEachWhile(QueryEachWhileConsumer consumer) {
+ qReadOnly.findEachWhile(consumer);
+ }
+
+ @Nullable
+ @Override
+ public MODEL_TYPE findUnique() {
+ return qReadOnly.findUnique();
}
@Override
- public Query apply(FetchPath fetchPath) {
- return q.apply(fetchPath);
+ public EbeanQuery apply(FetchPath fetchPath) {
+ q.apply(fetchPath);
+ qReadOnly.apply(fetchPath);
+ return this;
}
@Override
@@ -70,8 +141,9 @@ public ExpressionList text() {
}
@Override
- public Query setUseDocStore(boolean b) {
+ public EbeanQuery setUseDocStore(boolean b) {
q.setUseDocStore(b);
+ qReadOnly.setUseDocStore(b);
return this;
}
@@ -87,28 +159,32 @@ public int delete() {
@Override
public Object getId() {
- return q.getId();
+ return qReadOnly.getId();
}
@Override
public Class getBeanType() {
- return q.getBeanType();
+ return qReadOnly.getBeanType();
}
@Override
- public Query setDisableLazyLoading(boolean b) {
- return q.setDisableLazyLoading(b);
+ public EbeanQuery setDisableLazyLoading(boolean b) {
+ q.setDisableLazyLoading(b);
+ qReadOnly.setDisableLazyLoading(b);
+ return this;
}
@Override
public EbeanQuery offset(int pos) {
q.setFirstRow(pos);
+ qReadOnly.setFirstRow(pos);
return this;
}
@Override
public EbeanQuery limit(int limit) {
q.setMaxRows(limit);
+ qReadOnly.setMaxRows(limit);
return this;
}
@@ -116,32 +192,42 @@ public EbeanQuery limit(int limit) {
public EbeanQuery orderBy(String... fieldList) {
E.illegalArgumentIf(fieldList.length == 0);
q.order(S.join(" ", fieldList));
+ qReadOnly.order(S.join(" ", fieldList));
return this;
}
@Override
public MODEL_TYPE first() {
- return q.findUnique();
+ List list = qReadOnly.setMaxRows(1).findList();
+ return list.isEmpty() ? null : list.get(0);
}
@Override
- public Query fetchQuery(String path, String fetchProperties) {
- return q.fetchQuery(path, fetchProperties);
+ public EbeanQuery fetchQuery(String path, String fetchProperties) {
+ q.fetchQuery(path, fetchProperties);
+ qReadOnly.fetchQuery(path, fetchProperties);
+ return this;
}
@Override
- public Query fetchLazy(String path, String fetchProperties) {
- return q.fetchLazy(path, fetchProperties);
+ public EbeanQuery fetchLazy(String path, String fetchProperties) {
+ q.fetchLazy(path, fetchProperties);
+ qReadOnly.fetchLazy(path, fetchProperties);
+ return this;
}
@Override
- public Query fetchQuery(String path) {
- return fetchQuery(path);
+ public EbeanQuery fetchQuery(String path) {
+ q.fetchQuery(path);
+ qReadOnly.fetchQuery(path);
+ return this;
}
@Override
- public Query fetchLazy(String path) {
- return fetchLazy(path);
+ public EbeanQuery fetchLazy(String path) {
+ q.fetchLazy(path);
+ qReadOnly.fetchLazy(path);
+ return this;
}
@Override
@@ -153,7 +239,7 @@ public Iterable fetch() {
}
qi.close();
return list;
-// we need to close the query iterable right now otherwise it hold the data connection forever
+// we need to close the query iterable right now otherwise it holds the data connection forever
// return new Iterable() {
// @Override
// public Iterator iterator() {
@@ -164,121 +250,137 @@ public Iterable fetch() {
@Override
public long count() {
- return q.findCount();
+ return qReadOnly.findCount();
}
// --- Ebean Query methods: delegate to q
@Override
- public Query setIncludeSoftDeletes() {
+ public EbeanQuery setIncludeSoftDeletes() {
q.setIncludeSoftDeletes();
+ qReadOnly.setIncludeSoftDeletes();
return this;
}
@Override
- public Query asDraft() {
- return q.asDraft();
+ public EbeanQuery asDraft() {
+ q.asDraft();
+ qReadOnly.asDraft();
+ return this;
}
@Override
public boolean isAutoTuned() {
- return q.isAutoTuned();
- }
-
- @Override
- public Query setAutoTune(boolean b) {
- return q.setAutoTune(b);
+ return qReadOnly.isAutoTuned();
}
@Override
- public Query setDisableReadAuditing() {
- return q.setDisableReadAuditing();
+ public EbeanQuery setAutoTune(boolean b) {
+ q.setAutoTune(b);
+ qReadOnly.setAutoTune(b);
+ return this;
}
@Override
- public RawSql getRawSql() {
- return q.getRawSql();
+ public EbeanQuery setDisableReadAuditing() {
+ q.setDisableReadAuditing();
+ qReadOnly.setDisableReadAuditing();
+ return this;
}
@Override
public EbeanQuery setRawSql(RawSql rawSql) {
q.setRawSql(rawSql);
+ qReadOnly.setRawSql(rawSql);
return this;
}
+ public void setDefaultRawSqlIfRequired() {
+ }
+
@Override
public void cancel() {
q.cancel();
+ qReadOnly.cancel();
}
@Override
public EbeanQuery copy() {
- q.copy();
- return this;
+ EbeanQuery copy = new EbeanQuery<>();
+ copy.q = q.copy();
+ copy.qReadOnly = qReadOnly.copy();
+ return copy;
}
@Override
public EbeanQuery setPersistenceContextScope(PersistenceContextScope scope) {
q.setPersistenceContextScope(scope);
+ qReadOnly.setPersistenceContextScope(scope);
return this;
}
@Override
public ExpressionFactory getExpressionFactory() {
- return q.getExpressionFactory();
+ return qReadOnly.getExpressionFactory();
}
@Override
public EbeanQuery setLazyLoadBatchSize(int lazyLoadBatchSize) {
q.setLazyLoadBatchSize(lazyLoadBatchSize);
+ qReadOnly.setLazyLoadBatchSize(lazyLoadBatchSize);
return this;
}
@Override
public EbeanQuery select(String fetchProperties) {
q.select(fetchProperties);
+ qReadOnly.select(fetchProperties);
return this;
}
@Override
public EbeanQuery fetch(String path, String fetchProperties) {
q.fetch(path, fetchProperties);
+ qReadOnly.fetch(path, fetchProperties);
return this;
}
@Override
public EbeanQuery fetch(String assocProperty, String fetchProperties, FetchConfig fetchConfig) {
q.fetch(assocProperty, fetchProperties, fetchConfig);
+ qReadOnly.fetch(assocProperty, fetchProperties, fetchConfig);
return this;
}
@Override
public EbeanQuery fetch(String path) {
q.fetch(path);
+ qReadOnly.fetch(path);
return this;
}
@Override
public EbeanQuery fetch(String path, FetchConfig joinConfig) {
q.fetch(path, joinConfig);
+ qReadOnly.fetch(path, joinConfig);
return this;
}
@Override
- public List