mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
928
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a80ab94479 | ||
|
|
e6f0ab90dc | ||
|
|
53f4739c8f | ||
|
|
c6e33ba3ac | ||
|
|
0e2528e542 | ||
|
|
6ecc10a35c | ||
|
|
59bd2bb251 | ||
|
|
9fa83cdd5a | ||
|
|
f383f3f759 | ||
|
|
0abcc9e06e | ||
|
|
4a594b32ef | ||
|
|
8b9f760cb2 | ||
|
|
1d1cf76b5e | ||
|
|
194c14b99a | ||
|
|
fa8c6839dd | ||
|
|
f8e4ce6b4c | ||
|
|
cce496016d | ||
|
|
2c4d5dc304 | ||
|
|
1c981130b6 | ||
|
|
c18d1fa288 | ||
|
|
5287d93a58 | ||
|
|
6e6055fb84 | ||
|
|
c2ea8b3d56 | ||
|
|
5885d724c4 | ||
|
|
90d028640d | ||
|
|
b8d92f1846 | ||
|
|
e41d2eed7f | ||
|
|
8c7a84be9c | ||
|
|
63116f25ec | ||
|
|
eac05571c8 | ||
|
|
a6ad043142 | ||
|
|
bcc8040afe | ||
|
|
ee73fd47d5 | ||
|
|
064b3ceaa4 | ||
|
|
54ada6e07b | ||
|
|
14181932ec | ||
|
|
0faa6a8efd | ||
|
|
f94eb9b75e | ||
|
|
817436b00d | ||
|
|
a089a36f9d | ||
|
|
1f1868fdd3 | ||
|
|
8ac49e537d | ||
|
|
1e44b81e87 | ||
|
|
133cf95c6d | ||
|
|
2caf4bcccd | ||
|
|
e8f0e2f4bf | ||
|
|
8bde42fb16 | ||
|
|
2bb1e40c44 | ||
|
|
1ac1e19db0 | ||
|
|
85a0eb0afb | ||
|
|
a6470b48ff | ||
|
|
ebde00a137 | ||
|
|
bb6425a0c1 | ||
|
|
abff32c418 | ||
|
|
75f26b1f62 | ||
|
|
fc4ee15a2a | ||
|
|
6cb21f3e73 | ||
|
|
18663c8983 | ||
|
|
0d9094984a | ||
|
|
bd05f2c2ba | ||
|
|
1cc167341b | ||
|
|
4a313245b5 | ||
|
|
8744435eb6 | ||
|
|
dfdcdcf321 | ||
|
|
e203d4d191 | ||
|
|
d4c345b989 | ||
|
|
85b21a02e8 | ||
|
|
541271efb7 | ||
|
|
4313fb6f58 | ||
|
|
489781f89d | ||
|
|
9180289551 | ||
|
|
b15958e766 | ||
|
|
49c64c1eb5 | ||
|
|
a53168bd00 | ||
|
|
c783f26340 | ||
|
|
050a3e2368 | ||
|
|
49b1bd54c3 | ||
|
|
f57db28f1c | ||
|
|
b22bffe770 | ||
|
|
b9047bf280 | ||
|
|
a6f5ab8074 | ||
|
|
60becb6346 | ||
|
|
11839aca5e | ||
|
|
86aed458dd | ||
|
|
fa4130ba8e | ||
|
|
77995fda0a | ||
|
|
5112253d19 | ||
|
|
89c3e23410 | ||
|
|
b8858d91f0 | ||
|
|
46a42f4ef7 | ||
|
|
42f9c8fd59 | ||
|
|
6560a46b2d | ||
|
|
4da86481e8 | ||
|
|
bde133ef79 | ||
|
|
8780ac0902 | ||
|
|
038db79737 | ||
|
|
bc055fea25 | ||
|
|
ab283efed7 | ||
|
|
d113ddc525 | ||
|
|
7c36439daf | ||
|
|
7193b035b2 | ||
|
|
de22b7bf27 | ||
|
|
694518db0a | ||
|
|
b721017dd5 | ||
|
|
de5346437f | ||
|
|
1669649706 | ||
|
|
3f816c49c9 | ||
|
|
e31ae49bc5 | ||
|
|
bdf8381518 | ||
|
|
7eb185ce9b | ||
|
|
f175b198e6 | ||
|
|
de734665cd | ||
|
|
c5eb6fa034 | ||
|
|
ee19fd17fa | ||
|
|
a7c6f9835a | ||
|
|
06b1babed9 | ||
|
|
5706c73272 | ||
|
|
c5a899c0e8 | ||
|
|
50eb7d78fb | ||
|
|
13e805b31c | ||
|
|
3531db0e53 | ||
|
|
87243a871d | ||
|
|
f2159fed71 | ||
|
|
740fd63f35 | ||
|
|
2ad99794ea | ||
|
|
775f184450 | ||
|
|
4492a87a3f | ||
|
|
18d5d01d48 | ||
|
|
90b1b88be6 | ||
|
|
6839f869f5 | ||
|
|
488762957a | ||
|
|
ec016cab17 | ||
|
|
7c28f01923 | ||
|
|
54da22eee6 | ||
|
|
6772b6e87e | ||
|
|
9856ebd540 | ||
|
|
f96ac6e6fe | ||
|
|
4c5618b04b | ||
|
|
a77de9e5e6 | ||
|
|
da29330a2a | ||
|
|
d0f9d4a9a6 | ||
|
|
61ee67ee41 | ||
|
|
3117acd2d7 | ||
|
|
4cee41d8d6 | ||
|
|
f4a58938bd | ||
|
|
4ce84f694f | ||
|
|
8eb248b966 | ||
|
|
c294d8e568 | ||
|
|
e923316ce9 | ||
|
|
f611068a03 | ||
|
|
dd880ac09b | ||
|
|
dbe24a4041 | ||
|
|
1f32dc2dc5 | ||
|
|
b2ce9db8a8 | ||
|
|
a626690918 | ||
|
|
0d511d51a6 | ||
|
|
854f467504 | ||
|
|
d3cc393edc | ||
|
|
002014f930 | ||
|
|
c8d352b0a8 | ||
|
|
3796f2b267 | ||
|
|
4ef5abceca | ||
|
|
4eda4201de | ||
|
|
933aa30149 | ||
|
|
0c80b3078a | ||
|
|
7317847aa7 | ||
|
|
444644f759 | ||
|
|
f704da641d | ||
|
|
a1d2f4c1af | ||
|
|
b7469da5b1 | ||
|
|
2897968a54 | ||
|
|
6360fad701 | ||
|
|
dbc97aa28c | ||
|
|
a231c136a9 | ||
|
|
c6487e56cf | ||
|
|
dac0a97a3f | ||
|
|
ff0274f72c | ||
|
|
ddee202bcc | ||
|
|
e1522a4a68 | ||
|
|
7bc6170587 | ||
|
|
0322c19261 | ||
|
|
18ae0a7833 | ||
|
|
e99db44ddf | ||
|
|
361de9ea99 | ||
|
|
99732b30b1 | ||
|
|
dd5e5819b8 | ||
|
|
b4330679b8 | ||
|
|
59447ad261 | ||
|
|
3bd20a424a | ||
|
|
4ac3a8d1ad | ||
|
|
5a8f8b3a83 | ||
|
|
7c01cec466 | ||
|
|
30ad4260f0 | ||
|
|
ab421d6f2b | ||
|
|
0b807addc7 | ||
|
|
bb03ef5693 | ||
|
|
248a7b1062 | ||
|
|
9da28262b4 | ||
|
|
fc8dd18fd1 | ||
|
|
70ba658442 | ||
|
|
70b730657f | ||
|
|
bf3cb7e2e2 | ||
|
|
c2708ecc76 | ||
|
|
896aba3053 | ||
|
|
f78b602a90 | ||
|
|
306c1b5cf6 | ||
|
|
cdf2718ca9 | ||
|
|
967ca0c9f3 | ||
|
|
607acb1b4e | ||
|
|
5f923945e9 | ||
|
|
11fbe8bf5b | ||
|
|
0544fa7ab4 | ||
|
|
51eed9bfe4 | ||
|
|
32ce1f1d59 | ||
|
|
f445c118a0 | ||
|
|
a8ff918bb3 | ||
|
|
729aeae0d7 | ||
|
|
17a9341287 | ||
|
|
c863014fec | ||
|
|
8170db4101 | ||
|
|
434a5117a2 | ||
|
|
85ed8cd784 | ||
|
|
9b70900267 | ||
|
|
0e33d58bb2 | ||
|
|
9d9d13060c | ||
|
|
e071eecd59 | ||
|
|
bc8e254a65 | ||
|
|
e0e369904c | ||
|
|
bd85ba17a1 | ||
|
|
8801b8d8ca | ||
|
|
ebd6c535ab | ||
|
|
5c771a7219 | ||
|
|
eb6f722385 | ||
|
|
cef4f59b2c | ||
|
|
67352ab3b2 | ||
|
|
4a21395cda | ||
|
|
fcd7f8b6cf | ||
|
|
4565719728 | ||
|
|
cbdf5609b2 | ||
|
|
f97359502b | ||
|
|
ffaf00c064 | ||
|
|
f6f9511d2a | ||
|
|
5e94c26094 | ||
|
|
5aaed4e12b | ||
|
|
c29a57b5ec | ||
|
|
998b8cc192 | ||
|
|
9c1d930fb8 | ||
|
|
d6d7537a9c | ||
|
|
92e83c49d9 | ||
|
|
d758590da4 | ||
|
|
21a5efa9b9 | ||
|
|
55a2cb12bb | ||
|
|
293700acc0 | ||
|
|
8980a3b6fd | ||
|
|
72efc5d7d6 | ||
|
|
84589fcce6 | ||
|
|
a0e44aedf3 | ||
|
|
41102aca35 | ||
|
|
548cea432e | ||
|
|
592cb37693 | ||
|
|
f2178bf0a6 | ||
|
|
5cae425b09 | ||
|
|
94b78f1c2d | ||
|
|
561affef0f | ||
|
|
3310d2186d | ||
|
|
02bdace144 | ||
|
|
7c17098f17 | ||
|
|
6f194ce95d | ||
|
|
dbe473d5a1 | ||
|
|
ed0e9e7006 | ||
|
|
2a03198393 | ||
|
|
6f1472abe0 | ||
|
|
6dea4f0890 | ||
|
|
4a4ec42cdc | ||
|
|
92ea8e3738 | ||
|
|
c349832d35 | ||
|
|
90493ad57d | ||
|
|
5012f59371 | ||
|
|
149e63a272 | ||
|
|
d52a00a8fb | ||
|
|
f0dcec95dd | ||
|
|
2653931881 | ||
|
|
85207086e6 | ||
|
|
d0b0b02d6a | ||
|
|
34fa1def77 | ||
|
|
9f1aa958fc | ||
|
|
cdc5eefc69 | ||
|
|
c9588586c9 | ||
|
|
52735179d9 | ||
|
|
cef1fb9e80 | ||
|
|
c7e1964aae | ||
|
|
6d43883f77 | ||
|
|
f06f99dfc3 | ||
|
|
41e600be45 | ||
|
|
62a81c531a | ||
|
|
2cb1a626c4 | ||
|
|
18cde36b9d | ||
|
|
e05b6b78ad | ||
|
|
58c49deb06 | ||
|
|
4a41e88162 | ||
|
|
2e5becf48c | ||
|
|
4094339407 | ||
|
|
bf24949efb | ||
|
|
3b4549a7ee | ||
|
|
f194fdb132 | ||
|
|
2d274c46fa | ||
|
|
b61e9af750 | ||
|
|
a01362abad | ||
|
|
4387c662b6 | ||
|
|
ecdd027b3e | ||
|
|
2b0f572f4d | ||
|
|
0a1704e6a9 | ||
|
|
854c208f92 | ||
|
|
e6f604764c | ||
|
|
9b501b3dc8 | ||
|
|
c2fb23a25c | ||
|
|
1ad7ace9bd | ||
|
|
6a3a7eafea | ||
|
|
896aed0b38 | ||
|
|
f7359aacd7 | ||
|
|
d77fb9265b | ||
|
|
73ea91d4c9 | ||
|
|
14839f0c0f | ||
|
|
db8f4e141d | ||
|
|
db27844eca | ||
|
|
61be1683b2 | ||
|
|
27a1f35356 | ||
|
|
f0c0b7ebcc | ||
|
|
f4c646cdc1 | ||
|
|
48abc73e50 | ||
|
|
91a327a5e7 | ||
|
|
a861e8bdcc | ||
|
|
7692d9782a | ||
|
|
524e3e31f0 | ||
|
|
d69d96a400 | ||
|
|
0ce39c73f1 | ||
|
|
82d6294dcb | ||
|
|
ba01103f48 | ||
|
|
3e14ec6a5a | ||
|
|
b9d5d35850 | ||
|
|
04adc35ccd | ||
|
|
bfc2b57df5 | ||
|
|
a5880fca97 | ||
|
|
8685f2056a | ||
|
|
2ac19bea1a | ||
|
|
9410f82f5a | ||
|
|
21382a52ed | ||
|
|
f871259f20 | ||
|
|
eb765056fd | ||
|
|
ddf3c753d6 | ||
|
|
4767aff046 | ||
|
|
75846edd97 | ||
|
|
f7c6745de1 | ||
|
|
f080f16e63 | ||
|
|
9135f87253 | ||
|
|
90ccf2d8b4 | ||
|
|
11409f8c09 | ||
|
|
fb472a0304 | ||
|
|
04c9007d22 | ||
|
|
8f75a04ad0 | ||
|
|
2236e4bfd7 | ||
|
|
6d1c3738de | ||
|
|
20160144f5 | ||
|
|
891166507d | ||
|
|
bce97b1063 | ||
|
|
c5b960c588 | ||
|
|
009b400ed3 | ||
|
|
b6ee6ade8c | ||
|
|
0891c067d5 | ||
|
|
7b3b32f0ff | ||
|
|
3878b02cff | ||
|
|
92995b807e | ||
|
|
907d36123d | ||
|
|
2db95f909d | ||
|
|
5213e8b653 | ||
|
|
2314fd267f | ||
|
|
b24f093bbb | ||
|
|
444c868124 | ||
|
|
81b16b8f73 | ||
|
|
850db70be3 | ||
|
|
ee81ee4d7c | ||
|
|
4cbeb282eb | ||
|
|
5278c010ba | ||
|
|
ea490a5ac3 | ||
|
|
e4390ed8a2 | ||
|
|
a23d9f7db8 | ||
|
|
b1704ff5dc | ||
|
|
c0d752b445 | ||
|
|
ef5ea59559 | ||
|
|
de42655bbd | ||
|
|
661230909c | ||
|
|
e9325a81f7 | ||
|
|
78b9066345 | ||
|
|
1959e01844 | ||
|
|
cf6179c86b | ||
|
|
168dacffa7 | ||
|
|
e0d322d80a | ||
|
|
1dd0f3cbf8 | ||
|
|
6961bf5787 | ||
|
|
a14288b06d | ||
|
|
171d1a19f4 | ||
|
|
cbaaad89ab | ||
|
|
413290a040 | ||
|
|
8feb100ac6 | ||
|
|
d236988035 | ||
|
|
df0d84424c | ||
|
|
fb30a15a5b | ||
|
|
3707d611b1 | ||
|
|
60aa720777 | ||
|
|
427152a894 | ||
|
|
3e43d544fb | ||
|
|
62b1da1be2 | ||
|
|
8b4eae2f91 | ||
|
|
4ed3a18b9d | ||
|
|
3c9d7e3127 | ||
|
|
a89744a7bd | ||
|
|
5962f14874 | ||
|
|
f161a38334 | ||
|
|
13f8da6b2e | ||
|
|
9ad14c5306 | ||
|
|
61ed4a5a74 | ||
|
|
275f2dbc98 | ||
|
|
521b6a36ef | ||
|
|
0a6c26e5d3 | ||
|
|
33416bffd0 | ||
|
|
4ce484f3f2 | ||
|
|
cacf033647 | ||
|
|
e3dba6bfe1 | ||
|
|
c0b6f291a1 | ||
|
|
9eab67d82e | ||
|
|
840cb2ee7b | ||
|
|
e0f171b638 | ||
|
|
2bb52a9581 | ||
|
|
f1cf94365c | ||
|
|
a894924e96 | ||
|
|
680a11a532 | ||
|
|
605150de5c | ||
|
|
5ff44703cf | ||
|
|
99175bf679 | ||
|
|
acff330b37 | ||
|
|
df63eeaa8c | ||
|
|
07aa39c5de | ||
|
|
c51a1b07a4 | ||
|
|
bb56725b12 | ||
|
|
099adcf6cd | ||
|
|
05be24b8b2 | ||
|
|
7d98355d39 | ||
|
|
56562915bf | ||
|
|
07f4ad2500 | ||
|
|
22e43f5fa7 | ||
|
|
3127bc2154 | ||
|
|
8aa1ed6676 | ||
|
|
8a0dea1218 | ||
|
|
1e266a1532 | ||
|
|
57cfd25eb5 | ||
|
|
2bcce2e648 | ||
|
|
f6e45a6999 | ||
|
|
fa3de7158e | ||
|
|
792785dabe | ||
|
|
d0cd74b400 | ||
|
|
71d762ab97 | ||
|
|
e00713aa29 | ||
|
|
d70a49e105 | ||
|
|
159a9a8e54 | ||
|
|
db027eb030 | ||
|
|
ec55b2f096 | ||
|
|
b854943a86 | ||
|
|
8a263d243c | ||
|
|
0a4f93adc5 | ||
|
|
ffb11019fa | ||
|
|
6fcac27dfe | ||
|
|
71295077a5 | ||
|
|
ddbad284ad | ||
|
|
1fcec429b0 | ||
|
|
c6062fe93e | ||
|
|
d8d35b7dd9 | ||
|
|
590cd07d67 | ||
|
|
5cd74bc468 | ||
|
|
502b20be67 | ||
|
|
b3077d44f6 | ||
|
|
d4b35cb445 | ||
|
|
91e7540a39 | ||
|
|
06bd60aaf7 | ||
|
|
3db2a69312 | ||
|
|
5a983b9e0d | ||
|
|
ab7b34779a | ||
|
|
c7aad6078e | ||
|
|
ccfe9c39cd | ||
|
|
dbdac04883 | ||
|
|
1d369c002d | ||
|
|
5a1be81603 | ||
|
|
dee73da1aa | ||
|
|
a7dde87c5f | ||
|
|
60fadd448d | ||
|
|
0140d09007 | ||
|
|
da5604a38d | ||
|
|
937df1395c | ||
|
|
89c05007c2 | ||
|
|
4cc9278183 | ||
|
|
9841a2c03a | ||
|
|
74929472d9 | ||
|
|
e274a4c512 | ||
|
|
5d93c44475 | ||
|
|
63b802d0b8 | ||
|
|
1d7e751b60 | ||
|
|
5f8690fb87 | ||
|
|
e093675444 | ||
|
|
a04594540c | ||
|
|
269f2de333 | ||
|
|
be12910aec | ||
|
|
996e582a85 | ||
|
|
aa4c6b7889 | ||
|
|
27a4e8951d | ||
|
|
1fc4082abe | ||
|
|
1c5d7a97e1 | ||
|
|
67c2e1d24c | ||
|
|
eb292e017e | ||
|
|
88839f7613 | ||
|
|
ca71fef74a | ||
|
|
6c91ed0c76 | ||
|
|
8761c0486d | ||
|
|
fee6a9f04a | ||
|
|
17ff04e2b9 | ||
|
|
aa11095d17 | ||
|
|
c2a30f786f | ||
|
|
9b0dd2b0c4 | ||
|
|
aa96d10491 | ||
|
|
dfefbecf44 | ||
|
|
738f19491a | ||
|
|
61257bea7f | ||
|
|
566a01d815 | ||
|
|
a7116d1606 | ||
|
|
615a2aea46 | ||
|
|
20d538c428 | ||
|
|
01054bf470 | ||
|
|
affd720390 | ||
|
|
7d77df58c5 | ||
|
|
51fad2dec6 | ||
|
|
997378ce72 | ||
|
|
1a8a43603e | ||
|
|
d2c88bf7c6 | ||
|
|
0929147b08 | ||
|
|
ecab219635 | ||
|
|
7a974320ed | ||
|
|
1b7dc83a9a | ||
|
|
9827d9056f | ||
|
|
c8d5d9b552 | ||
|
|
dac55ab8e9 | ||
|
|
de75bcdaf9 | ||
|
|
5785124a2b | ||
|
|
4d1c0bfaa8 | ||
|
|
9a29c988cd | ||
|
|
80309f844e | ||
|
|
56ddc49ab4 | ||
|
|
1e7de83019 | ||
|
|
1db1f0312a | ||
|
|
09fa406f84 | ||
|
|
50d22ba357 | ||
|
|
c6f9d193be | ||
|
|
d27bf14887 | ||
|
|
d4e7d4eebc | ||
|
|
30c44d0928 | ||
|
|
443c5dba58 | ||
|
|
f24b4dba71 | ||
|
|
a474880735 | ||
|
|
4cfab3a2de | ||
|
|
4807070147 | ||
|
|
e00aa479ae | ||
|
|
b665d8375c | ||
|
|
4e74c68603 | ||
|
|
2694aa3fe1 | ||
|
|
f7a28aa904 | ||
|
|
4bc2559e8e | ||
|
|
c2faf0e0a7 | ||
|
|
895b331e8f | ||
|
|
8890079b80 | ||
|
|
20dd33ebca | ||
|
|
e2a1489743 | ||
|
|
d6bab46ac3 | ||
|
|
573673ef2b | ||
|
|
eb69499ca3 | ||
|
|
d9323b8ab6 | ||
|
|
a01ba128e5 | ||
|
|
fdc67b3ce5 | ||
|
|
5d433ff603 | ||
|
|
a3f9c4c889 | ||
|
|
769fc485ec | ||
|
|
61ef4fa420 | ||
|
|
8cf37e2f0a | ||
|
|
80a764a448 | ||
|
|
6621c5dfbb | ||
|
|
5e7dda1ec8 | ||
|
|
7bc6368f69 | ||
|
|
fb5a69adea | ||
|
|
0e7607bb27 | ||
|
|
1098b572fe | ||
|
|
7a6662a2dc | ||
|
|
1c6c812d4d | ||
|
|
e58a85f0af | ||
|
|
e3551152bb | ||
|
|
5138d1723f | ||
|
|
9b5ab542d7 | ||
|
|
f0bc4c786c | ||
|
|
b98739bb49 | ||
|
|
fcadc63338 | ||
|
|
3574479627 | ||
|
|
cecf2fc650 | ||
|
|
a1dab24414 | ||
|
|
c12ea28ea9 | ||
|
|
a2b418df8b | ||
|
|
2fb533a606 | ||
|
|
5d89897bbd | ||
|
|
9640e02b6a | ||
|
|
8a0ef33f79 | ||
|
|
d2ece76ca8 | ||
|
|
3495d03706 | ||
|
|
bc90fa50d7 | ||
|
|
777fc0ff30 | ||
|
|
9413f72939 | ||
|
|
1416647d04 | ||
|
|
63bddb4d54 | ||
|
|
6fddd418a1 | ||
|
|
faba55d772 | ||
|
|
ac6db11e3d | ||
|
|
ca7d8ecfc1 | ||
|
|
46eeee68c9 | ||
|
|
c1487daea8 | ||
|
|
b329ae42db | ||
|
|
13429daddc | ||
|
|
98a80295fe | ||
|
|
f8587368ee | ||
|
|
8ae2ae7f8b | ||
|
|
46f3b74b38 | ||
|
|
df51ccd2c4 | ||
|
|
730d43c008 | ||
|
|
81c2c804a6 | ||
|
|
533be356f2 | ||
|
|
589191f3f4 | ||
|
|
0e65efea57 | ||
|
|
be66872249 | ||
|
|
85a0354d42 | ||
|
|
0b8613fd4c | ||
|
|
e734c0010c | ||
|
|
e08333ef26 | ||
|
|
4a3eabbd6b | ||
|
|
ae68d41519 | ||
|
|
722692d934 | ||
|
|
21a3f322e1 | ||
|
|
0d175557b0 | ||
|
|
57ccd19fe6 | ||
|
|
9674711516 | ||
|
|
9155716752 | ||
|
|
d7d8c3e651 | ||
|
|
16f6f2ee7f | ||
|
|
fea6dfd62b | ||
|
|
464ed4322e | ||
|
|
c3f556f0dc | ||
|
|
ba6810891e | ||
|
|
c530883e5e | ||
|
|
06542b031e | ||
|
|
4b5365e708 | ||
|
|
1d471fee92 | ||
|
|
3825dea00a | ||
|
|
3fd130ac4c | ||
|
|
196645e7a2 | ||
|
|
f5459920e9 | ||
|
|
ee6452cfb0 | ||
|
|
ad7e18561b | ||
|
|
c640524bfc | ||
|
|
fea840c859 | ||
|
|
bb7df71391 | ||
|
|
cb6f0335b1 | ||
|
|
762899ef10 | ||
|
|
848d4f031e | ||
|
|
481f828507 | ||
|
|
b3d0c21a80 | ||
|
|
a115cdf095 | ||
|
|
410e9d475b | ||
|
|
462385c7d0 | ||
|
|
3655e2c6f8 | ||
|
|
318f6ae3f5 | ||
|
|
c63acad7e0 | ||
|
|
6dba4a3d28 | ||
|
|
ecf1e53616 | ||
|
|
0ff9a00427 | ||
|
|
725ff8dc58 | ||
|
|
a780dc133e | ||
|
|
b111fcfecc | ||
|
|
114693b7cd | ||
|
|
5a39dcb39c | ||
|
|
b04f887bc3 | ||
|
|
5c38561049 | ||
|
|
f40eb011c3 | ||
|
|
a08cf548e7 | ||
|
|
f12f0d7f7a | ||
|
|
0c53efcbbc | ||
|
|
1aeed8ad12 | ||
|
|
bcb136b692 | ||
|
|
8b670fd615 | ||
|
|
970bc8e973 | ||
|
|
007b06e9db | ||
|
|
4513dbf29d | ||
|
|
53bcc62a0c | ||
|
|
858c55c978 | ||
|
|
cedba089e1 | ||
|
|
cbf7811f7c | ||
|
|
ea13b322ca | ||
|
|
486a8cf1c0 | ||
|
|
bfe46432da | ||
|
|
272eae5f22 | ||
|
|
502104eba8 | ||
|
|
fa45c79bd2 | ||
|
|
ee4d1bf866 | ||
|
|
dcf7b60d37 | ||
|
|
0663a97941 | ||
|
|
f31ab4d6a8 | ||
|
|
f77388738b | ||
|
|
945175c533 | ||
|
|
7d37c6cfd8 | ||
|
|
496672b394 | ||
|
|
1ffe359573 | ||
|
|
23cd9b6a93 | ||
|
|
333ac8edd9 | ||
|
|
081cb20260 | ||
|
|
53f1da32be | ||
|
|
5544a2cc3e | ||
|
|
84c3008db1 | ||
|
|
d949d4d6a2 | ||
|
|
03669dc307 | ||
|
|
2a8fad7364 | ||
|
|
e62db11f01 | ||
|
|
8c8f2b95da | ||
|
|
576eb01187 | ||
|
|
8b18b2a20e | ||
|
|
f5c12a916d | ||
|
|
2f8a99c304 | ||
|
|
cd9a43c3ab | ||
|
|
f251ca5431 | ||
|
|
2c44c80f65 | ||
|
|
d9efeac0a1 | ||
|
|
f4a7d0b6ad | ||
|
|
bc5db1e46a | ||
|
|
8743148238 | ||
|
|
68db6723d0 | ||
|
|
9b1fa43792 | ||
|
|
5f2454831e | ||
|
|
140178bb47 | ||
|
|
f95b4b5c4b | ||
|
|
d3b3a79342 | ||
|
|
52398317bc | ||
|
|
7f2e4f54ff | ||
|
|
9f19ed5376 | ||
|
|
d49a7c415f | ||
|
|
8ffc9ede85 | ||
|
|
eba521563a | ||
|
|
ed71e106df | ||
|
|
050ae49f6b | ||
|
|
d5d9a897ae | ||
|
|
ddf200ffdd | ||
|
|
7fa5e2aa8c | ||
|
|
8bfae9deef | ||
|
|
e6c9f151c1 | ||
|
|
30a0935300 | ||
|
|
b4182d4519 | ||
|
|
93cc0399f1 | ||
|
|
5404dab5a3 | ||
|
|
d70da1d805 | ||
|
|
2225d5b7e8 | ||
|
|
270369bd65 | ||
|
|
a932d61a94 | ||
|
|
24b08663af | ||
|
|
bb6c9c84ba | ||
|
|
a1e185b0f6 | ||
|
|
e2a467ca5a | ||
|
|
4b28933298 | ||
|
|
6077acf134 | ||
|
|
8a4ffd21ab | ||
|
|
d1314124af | ||
|
|
36f018b6aa | ||
|
|
87ccb6e333 | ||
|
|
3432c365f6 | ||
|
|
b7d5aa344f | ||
|
|
7e768623e4 | ||
|
|
73ab2ee1fe | ||
|
|
122fed448c | ||
|
|
6e52bee91f | ||
|
|
cc26afad13 | ||
|
|
bf20449fb5 | ||
|
|
6af5fae8e9 | ||
|
|
e26a38ecaa | ||
|
|
1cdf68f1c0 | ||
|
|
2923dd1d96 | ||
|
|
9067508e1d | ||
|
|
385cc76e34 | ||
|
|
c14cb4b85e | ||
|
|
52644647e4 | ||
|
|
3bf9dd6743 | ||
|
|
aececa2199 | ||
|
|
b4e22a4ca7 | ||
|
|
9b8b4414c4 | ||
|
|
b8fd2c7a02 | ||
|
|
a94f5d74ca | ||
|
|
3829613c37 | ||
|
|
0762eaf0ab | ||
|
|
7fbdab6220 | ||
|
|
cf4d45befb | ||
|
|
dcd81a857d | ||
|
|
0cac723eac | ||
|
|
c6ba4d8155 | ||
|
|
201958f38c | ||
|
|
9326c9c79e | ||
|
|
1042fdb280 | ||
|
|
197056dbc5 | ||
|
|
895b5ee4ff | ||
|
|
c839fe6520 | ||
|
|
2678f85506 | ||
|
|
2b1b4af7a2 | ||
|
|
4218b8a2e8 | ||
|
|
fe7d73a4a4 | ||
|
|
81e86b07e3 | ||
|
|
910c04e373 | ||
|
|
205f1f5e89 | ||
|
|
a1a6d2b725 | ||
|
|
30da589ea0 | ||
|
|
c66e9547e1 | ||
|
|
73990e3fb7 | ||
|
|
f7920de3c2 | ||
|
|
3dd5069f5a | ||
|
|
1d363776ec | ||
|
|
c512eb564d | ||
|
|
7f332e91ff | ||
|
|
8e9d644bc6 | ||
|
|
fa5ce9cbba | ||
|
|
b7905daeb5 | ||
|
|
9da7c9468e | ||
|
|
9eee224e03 | ||
|
|
906d5f04ad | ||
|
|
654c3f7f67 | ||
|
|
c61e6b04a2 | ||
|
|
f893653090 | ||
|
|
579c1efcf6 | ||
|
|
662f9cdeb3 | ||
|
|
b4782425f8 | ||
|
|
2648423930 | ||
|
|
b62cea5073 | ||
|
|
c10ad11b8b | ||
|
|
4aa8a0dc63 | ||
|
|
e4569f9362 | ||
|
|
ed83bababc | ||
|
|
b746c83ed7 | ||
|
|
8e45462c2c | ||
|
|
9fdb375229 | ||
|
|
7e6d059ef1 | ||
|
|
856a3a6fdd | ||
|
|
f94c3e81e5 | ||
|
|
4bf9e2b18e | ||
|
|
112de29964 | ||
|
|
c5d761076a | ||
|
|
4bedefa494 | ||
|
|
a5e3a70921 | ||
|
|
f6f4368048 | ||
|
|
e700f1c83c | ||
|
|
dc5ac02952 | ||
|
|
b89371acd1 | ||
|
|
6c88325dad | ||
|
|
ecec966a85 | ||
|
|
c46ac04c0a | ||
|
|
25e6d05542 | ||
|
|
d3ead5d2f9 | ||
|
|
28a70fa550 | ||
|
|
cf31830cbc | ||
|
|
b4105ab5d0 | ||
|
|
1bb2b1318e | ||
|
|
65fa1c056b | ||
|
|
242945aa18 | ||
|
|
5e77be6e6d | ||
|
|
8c0d6b1a72 | ||
|
|
86436ac3ac | ||
|
|
ae228d6b0e | ||
|
|
410d1a9b37 | ||
|
|
f667a73dc1 | ||
|
|
4509c6b1ed | ||
|
|
d32559baf4 | ||
|
|
2639e799c5 | ||
|
|
46c66b7169 | ||
|
|
30ae435f33 | ||
|
|
4f4743807c | ||
|
|
7b7a492241 | ||
|
|
4af8e53315 | ||
|
|
1c6fa575f2 | ||
|
|
2430404e1f | ||
|
|
d433e0ea46 | ||
|
|
42591a5a87 | ||
|
|
65a62bf683 | ||
|
|
3e3f3c35e7 | ||
|
|
f4db7ca0bb | ||
|
|
b0e487cfbd | ||
|
|
23fd29ddf1 | ||
|
|
f21cac5d4f | ||
|
|
c2e5619f70 | ||
|
|
18e0ff7067 | ||
|
|
4119c02f0d | ||
|
|
8985d37aed | ||
|
|
23e035894f | ||
|
|
32b8fd0e26 | ||
|
|
4971db54c8 | ||
|
|
e417b3cde2 | ||
|
|
d23ca31e42 | ||
|
|
5e1aa47c05 | ||
|
|
21dd8cee37 | ||
|
|
ece82996c2 | ||
|
|
fa520c95ea | ||
|
|
a6685141a4 | ||
|
|
78ab0ad923 | ||
|
|
4fb67a4c8c | ||
|
|
dd94e60d16 | ||
|
|
aa70e17657 | ||
|
|
016cd3fb71 | ||
|
|
17f28ba0aa | ||
|
|
ab88a879e9 | ||
|
|
5b85f3c8dd | ||
|
|
16a5100f35 | ||
|
|
86b2c5d5b5 | ||
|
|
e0c3198ee6 | ||
|
|
12bdd847b5 | ||
|
|
9860816ab7 | ||
|
|
e17283726a | ||
|
|
eff61ae5fc |
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
custom: https://ebean.io/sponsors
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
sudo: required
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- openjdk11
|
||||
|
||||
git:
|
||||
depth: 3
|
||||
|
||||
addons:
|
||||
postgresql: "9.6"
|
||||
postgresql: 10
|
||||
# apt:
|
||||
# packages:
|
||||
# - mysql-server-5.7
|
||||
|
||||
@@ -7,4 +7,11 @@ do
|
||||
echo ${file}
|
||||
cat ${file}
|
||||
echo
|
||||
done
|
||||
done
|
||||
|
||||
for file in ebean-autotune/target/surefire-reports/*.txt
|
||||
do
|
||||
echo ${file}
|
||||
cat ${file}
|
||||
echo
|
||||
done
|
||||
|
||||
@@ -1,6 +1,34 @@
|
||||
[](https://travis-ci.org/ebean-orm/ebean)
|
||||
[](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean)
|
||||
|
||||
# Sponsors
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.foconis.de/" target="_blank">
|
||||
<img width="222px" src="https://www.foconis.de/templates/yootheme/cache/foconis_logo_322-709da1de.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.payintech.com/" target="_blank">
|
||||
<img width="222px" src="https://ebean.io/images/sponsor_PayinTech-logo-noir.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.premium-minds.com" target="_blank">
|
||||
<img width="222px" src="https://ebean.io/images/logo-med-principal.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://timerbee.de" target="_blank">
|
||||
<img width="222px" src="https://ebean.io/images/logo-timerbee.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
# Need help?
|
||||
Post questions or issues to the Ebean google group - https://groups.google.com/forum/#!forum/ebean
|
||||
|
||||
@@ -16,4 +44,3 @@ Goto [https://ebean.io/docs/](https://ebean.io/docs/)
|
||||
## Other versions
|
||||
* [](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-agent) - ebean-agent
|
||||
* [](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-maven-plugin) - ebean-maven-plugin
|
||||
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>12.5.2</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
<description>ebean api</description>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
|
||||
<properties>
|
||||
<jackson-core.version>2.11.3</jackson-core.version>
|
||||
<jackson-databind.version>2.11.3</jackson-databind.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!--
|
||||
Projects are expected to explicit depend on version
|
||||
of slf4j that they want to use
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.25</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-config</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Class retention Nonnull and Nullable annotations
|
||||
to assist with IDE auto-completion with Ebean API
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-jsr305</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
<version>2.2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-annotation</artifactId>
|
||||
<version>6.13</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-types</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-datasource</artifactId>
|
||||
<version>6.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>12.1.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson core used internally by Ebean -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson-core.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- provided scope for JsonNode support -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson-databind.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Provided scope so that the H2HistoryTrigger can live in Ebean core
|
||||
and not require a separate module for it -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.199</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.transaction</groupId>
|
||||
<artifactId>jta</artifactId>
|
||||
<version>1.1</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- provided scope to read validation annotations Size etc -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.1.0.Final</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
+5
-2
@@ -31,15 +31,18 @@ public interface BackgroundExecutor {
|
||||
* Execute a task periodically with a fixed delay between each execution.
|
||||
* <p>
|
||||
* For example, execute a runnable every minute.
|
||||
* </p>
|
||||
* <p>
|
||||
* The delay is the time between executions no matter how long the task took.
|
||||
* That is, this method has the same behaviour characteristics as
|
||||
* {@link ScheduledExecutorService#scheduleWithFixedDelay(Runnable, long, long, TimeUnit)}
|
||||
* </p>
|
||||
*/
|
||||
void executePeriodically(Runnable r, long delay, TimeUnit unit);
|
||||
|
||||
/**
|
||||
* Execute a task periodically additionally with an initial delay different from delay.
|
||||
*/
|
||||
void executePeriodically(Runnable r, long initialDelay, long delay, TimeUnit unit);
|
||||
|
||||
/**
|
||||
* Schedules a Runnable for one-shot action that becomes enabled after the given delay.
|
||||
*
|
||||
+1
-1
@@ -14,7 +14,7 @@ import java.util.Optional;
|
||||
*
|
||||
* public class CustomerFinder extends BeanFinder<Long,Customer> {
|
||||
*
|
||||
* @Inject
|
||||
* @Inject
|
||||
* public CustomerFinder(Database database) {
|
||||
* super(Customer.class, database);
|
||||
* }
|
||||
+2
-2
@@ -9,10 +9,10 @@ import java.util.Collection;
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* @Repository
|
||||
* @Repository
|
||||
* public class CustomerRepository extends BeanRepository<Long,Customer> {
|
||||
*
|
||||
* @Inject
|
||||
* @Inject
|
||||
* public CustomerRepository(Database server) {
|
||||
* super(Customer.class, server);
|
||||
* }
|
||||
+2
-2
@@ -69,8 +69,8 @@ public enum CacheMode {
|
||||
*/
|
||||
GET(true, false);
|
||||
|
||||
private boolean get;
|
||||
private boolean put;
|
||||
private final boolean get;
|
||||
private final boolean put;
|
||||
|
||||
CacheMode(boolean get, boolean put) {
|
||||
this.get = get;
|
||||
@@ -2,7 +2,6 @@ package io.ebean;
|
||||
|
||||
import io.ebean.annotation.TxIsolation;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
@@ -61,7 +60,9 @@ import java.util.concurrent.Callable;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public class DB {
|
||||
public final class DB {
|
||||
|
||||
private static final DbContext context = DbContext.getInstance();
|
||||
|
||||
/**
|
||||
* Hide constructor.
|
||||
@@ -69,11 +70,18 @@ public class DB {
|
||||
private DB() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Backdoor for registering a mock implementation of Database as the default database.
|
||||
*/
|
||||
protected static Database mock(String name, Database server, boolean defaultServer) {
|
||||
return context.mock(name, server, defaultServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default database.
|
||||
*/
|
||||
public static Database getDefault() {
|
||||
return Ebean.getDefaultServer();
|
||||
return context.getDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,25 +90,24 @@ public class DB {
|
||||
* @param name The name of the database
|
||||
*/
|
||||
public static Database byName(String name) {
|
||||
return Ebean.getServer(name);
|
||||
return context.get(name);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Register the server with this Ebean singleton. Specify if the registered
|
||||
// * server is the primary/default server.
|
||||
// */
|
||||
// public static void register(EbeanServer server, boolean defaultServer) {
|
||||
// serverMgr.register(server, defaultServer);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Backdoor for registering a mock implementation of EbeanServer as the default server.
|
||||
// */
|
||||
// protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
|
||||
// EbeanServer originalPrimaryServer = serverMgr.defaultServer;
|
||||
// serverMgr.registerWithName(name, server, defaultServer);
|
||||
// return originalPrimaryServer;
|
||||
// }
|
||||
/**
|
||||
* Return the ScriptRunner for the default database.
|
||||
* <p>
|
||||
* Useful to run SQL scripts that are resources. For example a test script
|
||||
* for inserting seed data for a particular test.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* DB.script().run("/scripts/test-script.sql")
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public static ScriptRunner script() {
|
||||
return getDefault().script();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ExpressionFactory from the default database.
|
||||
@@ -177,6 +184,18 @@ public class DB {
|
||||
return getDefault().beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new transaction that is not held in TransactionThreadLocal.
|
||||
* <p>
|
||||
* You will want to do this if you want multiple Transactions in a single
|
||||
* thread or generally use transactions outside of the TransactionThreadLocal
|
||||
* management.
|
||||
* </p>
|
||||
*/
|
||||
public static Transaction createTransaction() {
|
||||
return getDefault().createTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a transaction additionally specifying the isolation level.
|
||||
*
|
||||
@@ -396,15 +415,6 @@ public class DB {
|
||||
* called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link DatabaseConfig#setUpdatesDeleteMissingChildren(boolean)}: </b> When cascade saving to a
|
||||
* OneToMany or ManyToMany the updatesDeleteMissingChildren setting controls if any other children
|
||||
* that are in the database but are not in the collection are deleted.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link DatabaseConfig#setUpdateChangesOnly(boolean)}: </b> The updateChangesOnly setting
|
||||
* controls if only the changed properties are included in the update or if all the loaded
|
||||
* properties are included instead.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // A 'stateless update' example
|
||||
@@ -414,9 +424,6 @@ public class DB {
|
||||
* database.update(customer);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see DatabaseConfig#setUpdatesDeleteMissingChildren(boolean)
|
||||
* @see DatabaseConfig#setUpdateChangesOnly(boolean)
|
||||
*/
|
||||
public static void update(Object bean) throws OptimisticLockException {
|
||||
getDefault().update(bean);
|
||||
@@ -455,6 +462,13 @@ public class DB {
|
||||
return getDefault().saveAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all the beans from a Collection.
|
||||
*/
|
||||
public static int saveAll(Object... beans) throws OptimisticLockException {
|
||||
return getDefault().saveAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks the uniqueness of a bean. I.e. if the save will work. It will return the
|
||||
* properties that violates an unique / primary key. This may be done in an UI save action to
|
||||
@@ -663,7 +677,7 @@ public class DB {
|
||||
* // find orders and their customers
|
||||
* List<Order> list = DB.find(Order.class)
|
||||
* .fetch("customer")
|
||||
* .orderBy("id")
|
||||
* .order("id")
|
||||
* .findList();
|
||||
*
|
||||
* // sort by customer name ascending, then by order shipDate
|
||||
@@ -749,8 +763,11 @@ public class DB {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to sqlQuery().
|
||||
* <p>
|
||||
* This is an alias for {@link #sqlQuery(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static SqlQuery createSqlQuery(String sql) {
|
||||
return sqlQuery(sql);
|
||||
}
|
||||
@@ -773,8 +790,11 @@ public class DB {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to sqlUpdate().
|
||||
* <p>
|
||||
* This is an alias for {@link #sqlUpdate(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static SqlUpdate createSqlUpdate(String sql) {
|
||||
return sqlUpdate(sql);
|
||||
}
|
||||
@@ -1215,6 +1235,13 @@ public class DB {
|
||||
return getDefault().getBeanState(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the Id property for a given bean.
|
||||
*/
|
||||
public static Object getBeanId(Object bean) {
|
||||
return getDefault().getBeanId(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the manager of the level 2 cache ("L2" cache).
|
||||
*/
|
||||
@@ -1237,4 +1264,18 @@ public class DB {
|
||||
return getDefault().json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the base tables for the given bean types.
|
||||
*/
|
||||
public static void truncate(Class<?>... types) {
|
||||
getDefault().truncate(types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the given tables.
|
||||
*/
|
||||
public static void truncate(String... tables) {
|
||||
getDefault().truncate(tables);
|
||||
}
|
||||
|
||||
}
|
||||
+63
-31
@@ -1,9 +1,9 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.annotation.TxIsolation;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.meta.MetaInfoManager;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.plugin.SpiServer;
|
||||
@@ -14,6 +14,7 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -93,6 +94,11 @@ import java.util.concurrent.Callable;
|
||||
*/
|
||||
public interface Database {
|
||||
|
||||
/**
|
||||
* Shutdown the Database instance.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
/**
|
||||
* Shutdown the Database instance programmatically.
|
||||
* <p>
|
||||
@@ -116,6 +122,16 @@ public interface Database {
|
||||
*/
|
||||
AutoTune getAutoTune();
|
||||
|
||||
/**
|
||||
* Return the associated DataSource for this Database instance.
|
||||
*/
|
||||
DataSource getDataSource();
|
||||
|
||||
/**
|
||||
* Return the associated read only DataSource for this Database instance (can be null).
|
||||
*/
|
||||
DataSource getReadOnlyDataSource();
|
||||
|
||||
/**
|
||||
* Return the name. This is used with {@link DB#byName(String)} to get a
|
||||
* Database that was registered with the DB singleton.
|
||||
@@ -123,7 +139,7 @@ public interface Database {
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Return the ExpressionFactory for this server.
|
||||
* Return the ExpressionFactory for this database.
|
||||
*/
|
||||
ExpressionFactory getExpressionFactory();
|
||||
|
||||
@@ -133,6 +149,25 @@ public interface Database {
|
||||
*/
|
||||
MetaInfoManager getMetaInfoManager();
|
||||
|
||||
/**
|
||||
* Return the platform used for this database instance.
|
||||
* <p>
|
||||
* Note many platforms have multiple specific platform types so often we want to
|
||||
* get the base platform via {@link Platform#base()}.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* Platform platform = database.getPlatform().base();
|
||||
* if (platform == Platform.MYSQL) {
|
||||
* // do MySql specific function
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @return platform for this database instance
|
||||
*/
|
||||
Platform getPlatform();
|
||||
|
||||
/**
|
||||
* Return the extended API intended for use by plugins.
|
||||
*/
|
||||
@@ -376,7 +411,7 @@ public interface Database {
|
||||
* // find orders and their customers
|
||||
* List<Order> list = database.find(Order.class)
|
||||
* .fetch("customer")
|
||||
* .orderBy("id")
|
||||
* .order("id")
|
||||
* .findList();
|
||||
*
|
||||
* // sort by customer name ascending, then by order shipDate
|
||||
@@ -465,8 +500,11 @@ public interface Database {
|
||||
SqlQuery sqlQuery(String sql);
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to sqlQuery().
|
||||
* <p>
|
||||
* This is an alias for {@link #sqlQuery(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
SqlQuery createSqlQuery(String sql);
|
||||
|
||||
/**
|
||||
@@ -485,8 +523,11 @@ public interface Database {
|
||||
SqlUpdate sqlUpdate(String sql);
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to sqlUpdate().
|
||||
* <p>
|
||||
* This is an alias for {@link #sqlUpdate(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
SqlUpdate createSqlUpdate(String sql);
|
||||
|
||||
/**
|
||||
@@ -856,7 +897,7 @@ public interface Database {
|
||||
* <pre>{@code
|
||||
* public class Order { ...
|
||||
*
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* List<OrderDetail> details;
|
||||
* ...
|
||||
* }
|
||||
@@ -876,6 +917,11 @@ public interface Database {
|
||||
*/
|
||||
int saveAll(Collection<?> beans) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Save all the beans.
|
||||
*/
|
||||
int saveAll(Object... beans) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Delete the bean.
|
||||
* <p>
|
||||
@@ -1051,7 +1097,6 @@ public interface Database {
|
||||
* Integer returnValue = (Integer) cs.getObject(3);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
*/
|
||||
int execute(CallableSql callableSql);
|
||||
|
||||
@@ -1196,17 +1241,6 @@ public interface Database {
|
||||
* <b>Optimistic Locking: </b> Note that if the version property is not set when update() is
|
||||
* called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link ServerConfig#setUpdatesDeleteMissingChildren(boolean)}: </b> When cascade saving to a
|
||||
* OneToMany or ManyToMany the updatesDeleteMissingChildren setting controls if any other children
|
||||
* that are in the database but are not in the collection are deleted.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link ServerConfig#setUpdateChangesOnly(boolean)}: </b> The updateChangesOnly setting
|
||||
* controls if only the changed properties are included in the update or if all the loaded
|
||||
* properties are included instead.
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // A 'stateless update' example
|
||||
@@ -1216,9 +1250,6 @@ public interface Database {
|
||||
* database.update(customer);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see ServerConfig#setUpdatesDeleteMissingChildren(boolean)
|
||||
* @see ServerConfig#setUpdateChangesOnly(boolean)
|
||||
*/
|
||||
void update(Object bean) throws OptimisticLockException;
|
||||
|
||||
@@ -1227,16 +1258,6 @@ public interface Database {
|
||||
*/
|
||||
void update(Object bean, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Update a bean additionally specifying a transaction and the deleteMissingChildren setting.
|
||||
*
|
||||
* @param bean the bean to update
|
||||
* @param transaction the transaction to use (can be null).
|
||||
* @param deleteMissingChildren specify false if you do not want 'missing children' of a OneToMany
|
||||
* or ManyToMany to be automatically deleted.
|
||||
*/
|
||||
void update(Object bean, Transaction transaction, boolean deleteMissingChildren) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Update a collection of beans. If there is no current transaction one is created and used to
|
||||
* update all the beans in the collection.
|
||||
@@ -1323,7 +1344,7 @@ public interface Database {
|
||||
* public void run() {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1372,7 +1393,7 @@ public interface Database {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* ...
|
||||
* return u1.getEmail();
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1580,4 +1601,15 @@ public interface Database {
|
||||
* </p>
|
||||
*/
|
||||
<T> Set<String> validateQuery(Query<T> query);
|
||||
|
||||
/**
|
||||
* Truncate all the given tables.
|
||||
*/
|
||||
void truncate(String... tables);
|
||||
|
||||
/**
|
||||
* Truncate the base tables for the given bean types.
|
||||
*/
|
||||
void truncate(Class<?>... tables);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.config.ContainerConfig;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.service.SpiContainer;
|
||||
import io.ebean.service.SpiContainerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* Creates Database instances.
|
||||
* <p>
|
||||
* This uses either DatabaseConfig or properties in the application.properties file to
|
||||
* configure and create a Database instance.
|
||||
* </p>
|
||||
* <p>
|
||||
* The Database instance can either be registered with the DB singleton or
|
||||
* not. The DB singleton effectively holds a map of Database by a name.
|
||||
* If the Database is registered with the DB singleton you can retrieve it
|
||||
* later via {@link DB#byName(String)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* One Database can be nominated as the 'default/primary' Database. Many
|
||||
* methods on the DB singleton such as {@link DB#find(Class)} are just a
|
||||
* convenient way of using the 'default/primary' Database.
|
||||
* </p>
|
||||
*/
|
||||
public class DatabaseFactory {
|
||||
|
||||
private static final ReentrantLock lock = new ReentrantLock(false);
|
||||
private static SpiContainer container;
|
||||
|
||||
static {
|
||||
EbeanVersion.getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the container with clustering configuration.
|
||||
* <p>
|
||||
* Call this prior to creating any Database instances or alternatively set the
|
||||
* ContainerConfig on the DatabaseConfig when creating the first Database instance.
|
||||
*/
|
||||
public static void initialiseContainer(ContainerConfig containerConfig) {
|
||||
lock.lock();
|
||||
try {
|
||||
getContainer(containerConfig);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using properties to configure the database.
|
||||
*/
|
||||
public static Database create(String name) {
|
||||
lock.lock();
|
||||
try {
|
||||
return getContainer(null).createServer(name);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the DatabaseConfig object to configure the database.
|
||||
*/
|
||||
public static Database create(DatabaseConfig config) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (config.getName() == null) {
|
||||
throw new PersistenceException("The name is null (it is required)");
|
||||
}
|
||||
Database server = createInternal(config);
|
||||
if (config.isRegister()) {
|
||||
DbPrimary.setSkip(true);
|
||||
DbContext.getInstance().register(server, config.isDefaultServer());
|
||||
}
|
||||
return server;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the DatabaseConfig additionally specifying a classLoader to use as the context class loader.
|
||||
*/
|
||||
public static Database createWithContextClassLoader(DatabaseConfig config, ClassLoader classLoader) {
|
||||
lock.lock();
|
||||
try {
|
||||
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
try {
|
||||
return DatabaseFactory.create(config);
|
||||
} finally {
|
||||
// set the currentContextLoader back
|
||||
Thread.currentThread().setContextClassLoader(currentContextLoader);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown gracefully all Database instances cleaning up any resources as required.
|
||||
* <p>
|
||||
* This is typically invoked via JVM shutdown hook and not explicitly called.
|
||||
* </p>
|
||||
*/
|
||||
public static void shutdown() {
|
||||
lock.lock();
|
||||
try {
|
||||
container.shutdown();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private static Database createInternal(DatabaseConfig config) {
|
||||
return getContainer(config.getContainerConfig()).createServer(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the EbeanContainer initialising it if necessary.
|
||||
*
|
||||
* @param containerConfig the configuration controlling clustering communication
|
||||
*/
|
||||
private static SpiContainer getContainer(ContainerConfig containerConfig) {
|
||||
// thread safe in that all calling methods hold lock
|
||||
if (container != null) {
|
||||
return container;
|
||||
}
|
||||
|
||||
if (containerConfig == null) {
|
||||
// effectively load configuration from ebean.properties
|
||||
Properties properties = DbPrimary.getProperties();
|
||||
containerConfig = new ContainerConfig();
|
||||
containerConfig.loadFromProperties(properties);
|
||||
}
|
||||
container = createContainer(containerConfig);
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the container instance using the configuration.
|
||||
*/
|
||||
protected static SpiContainer createContainer(ContainerConfig containerConfig) {
|
||||
Iterator<SpiContainerFactory> factories = ServiceLoader.load(SpiContainerFactory.class).iterator();
|
||||
if (factories.hasNext()) {
|
||||
return factories.next().create(containerConfig);
|
||||
}
|
||||
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.config.BeanNotEnhancedException;
|
||||
import io.ebean.datasource.DataSourceConfigurationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* Holds Database instances.
|
||||
*/
|
||||
final class DbContext {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DbContext.class);
|
||||
|
||||
static {
|
||||
EbeanVersion.getVersion();
|
||||
}
|
||||
|
||||
private static final DbContext INSTANCE = new DbContext();
|
||||
|
||||
private final ConcurrentHashMap<String, Database> concMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final HashMap<String, Database> syncMap = new HashMap<>();
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock(false);
|
||||
|
||||
/**
|
||||
* The 'default' Database.
|
||||
*/
|
||||
private Database defaultDatabase;
|
||||
|
||||
private DbContext() {
|
||||
try {
|
||||
if (!DbPrimary.isSkip()) {
|
||||
// look to see if there is a default server defined
|
||||
String defaultName = DbPrimary.getDefaultServerName();
|
||||
logger.debug("defaultName:{}", defaultName);
|
||||
if (defaultName != null && !defaultName.trim().isEmpty()) {
|
||||
defaultDatabase = getWithCreate(defaultName.trim());
|
||||
}
|
||||
}
|
||||
} catch (BeanNotEnhancedException e) {
|
||||
throw e;
|
||||
|
||||
} catch (DataSourceConfigurationException e) {
|
||||
String msg = "Configuration error creating DataSource for the default Database." +
|
||||
" This typically means a missing application-test.yaml or missing ebean-test dependency." +
|
||||
" See https://ebean.io/docs/trouble-shooting#datasource";
|
||||
throw new DataSourceConfigurationException(msg, e);
|
||||
|
||||
} catch (Throwable e) {
|
||||
logger.error("Error trying to create the default Database", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the shared singleton instance.
|
||||
*/
|
||||
static DbContext getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default database.
|
||||
*/
|
||||
Database getDefault() {
|
||||
if (defaultDatabase == null) {
|
||||
String msg = "The default Database has not been defined?";
|
||||
msg += " This is normally set via the ebean.datasource.default property.";
|
||||
msg += " Otherwise it should be registered programmatically via registerServer()";
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
return defaultDatabase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database by name.
|
||||
*/
|
||||
Database get(String name) {
|
||||
if (name == null || name.isEmpty()) {
|
||||
return defaultDatabase;
|
||||
}
|
||||
Database server = concMap.get(name);
|
||||
if (server != null) {
|
||||
return server;
|
||||
}
|
||||
return getWithCreate(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read, create and put of Databases.
|
||||
*/
|
||||
private Database getWithCreate(String name) {
|
||||
lock.lock();
|
||||
try {
|
||||
Database server = syncMap.get(name);
|
||||
if (server == null) {
|
||||
// register when creating server this way
|
||||
server = DatabaseFactory.create(name);
|
||||
register(server, false);
|
||||
}
|
||||
return server;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a server so we can get it by its name.
|
||||
*/
|
||||
void register(Database server, boolean isDefault) {
|
||||
registerWithName(server.getName(), server, isDefault);
|
||||
}
|
||||
|
||||
private void registerWithName(String name, Database server, boolean isDefault) {
|
||||
lock.lock();
|
||||
try {
|
||||
concMap.put(name, server);
|
||||
syncMap.put(name, server);
|
||||
if (isDefault) {
|
||||
defaultDatabase = server;
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
Database mock(String name, Database server, boolean defaultServer) {
|
||||
Database originalPrimaryServer = this.defaultDatabase;
|
||||
registerWithName(name, server, defaultServer);
|
||||
return originalPrimaryServer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.config.Config;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* Provides singleton state for the default database.
|
||||
* <p/>
|
||||
* Intended for internal use as part of bootup, construction, registration of the default database.
|
||||
*/
|
||||
class DbPrimary {
|
||||
|
||||
private static final ReentrantLock lock = new ReentrantLock(false);
|
||||
private static String defaultServerName;
|
||||
private static boolean skip;
|
||||
|
||||
/**
|
||||
* Set whether to skip automatically creating the primary database.
|
||||
*/
|
||||
static void setSkip(boolean skip) {
|
||||
lock.lock();
|
||||
try {
|
||||
DbPrimary.skip = skip;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true to skip automatically creating the primary database.
|
||||
*/
|
||||
static boolean isSkip() {
|
||||
lock.lock();
|
||||
try {
|
||||
return skip;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default database name.
|
||||
*/
|
||||
static String getDefaultServerName() {
|
||||
lock.lock();
|
||||
try {
|
||||
getProperties();
|
||||
return defaultServerName;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default configuration Properties.
|
||||
*/
|
||||
static Properties getProperties() {
|
||||
lock.lock();
|
||||
try {
|
||||
if (defaultServerName == null) {
|
||||
defaultServerName = determineDefaultServerName();
|
||||
}
|
||||
return Config.asProperties();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine and return the default server name checking system environment variables and then global properties.
|
||||
*/
|
||||
private static String determineDefaultServerName() {
|
||||
String defaultServerName = System.getenv("EBEAN_DB");
|
||||
defaultServerName = System.getProperty("db", defaultServerName);
|
||||
defaultServerName = System.getProperty("ebean_db", defaultServerName);
|
||||
if (isEmpty(defaultServerName)) {
|
||||
defaultServerName = Config.get("datasource.default", null);
|
||||
if (isEmpty(defaultServerName)) {
|
||||
defaultServerName = Config.get("ebean.default.datasource", null);
|
||||
}
|
||||
}
|
||||
if (defaultServerName == null) {
|
||||
defaultServerName = "db";
|
||||
}
|
||||
return defaultServerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the string is null or empty.
|
||||
*/
|
||||
private static boolean isEmpty(String value) {
|
||||
return value == null || value.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
+16
-16
@@ -1,7 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebeanservice.docstore.api.DocQueryRequest;
|
||||
import io.ebeanservice.docstore.api.RawDoc;
|
||||
import io.ebean.docstore.DocQueryContext;
|
||||
import io.ebean.docstore.RawDoc;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -61,7 +61,7 @@ public interface DocumentStore {
|
||||
* <pre>{@code
|
||||
*
|
||||
* Customer customer =
|
||||
* server.find(Customer.class)
|
||||
* database.find(Customer.class)
|
||||
* .setUseDocStore(true)
|
||||
* .setId(42)
|
||||
* .findOne();
|
||||
@@ -69,7 +69,7 @@ public interface DocumentStore {
|
||||
* }</pre>
|
||||
*/
|
||||
@Nullable
|
||||
<T> T find(DocQueryRequest<T> request);
|
||||
<T> T find(DocQueryContext<T> request);
|
||||
|
||||
/**
|
||||
* Execute the find list query. This request is prepared to execute secondary queries.
|
||||
@@ -79,14 +79,14 @@ public interface DocumentStore {
|
||||
* <pre>{@code
|
||||
*
|
||||
* List<Customer> newCustomers =
|
||||
* server.find(Customer.class)
|
||||
* database.find(Customer.class)
|
||||
* .setUseDocStore(true)
|
||||
* .where().eq("status, Customer.Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
<T> List<T> findList(DocQueryRequest<T> request);
|
||||
<T> List<T> findList(DocQueryContext<T> request);
|
||||
|
||||
/**
|
||||
* Execute the query against the document store returning the paged list.
|
||||
@@ -99,7 +99,7 @@ public interface DocumentStore {
|
||||
* <pre>{@code
|
||||
*
|
||||
* PagedList<Customer> newCustomers =
|
||||
* server.find(Customer.class)
|
||||
* database.find(Customer.class)
|
||||
* .setUseDocStore(true)
|
||||
* .where().eq("status, Customer.Status.NEW)
|
||||
* .setMaxRows(50)
|
||||
@@ -107,7 +107,7 @@ public interface DocumentStore {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
<T> PagedList<T> findPagedList(DocQueryRequest<T> request);
|
||||
<T> PagedList<T> findPagedList(DocQueryContext<T> request);
|
||||
|
||||
/**
|
||||
* Execute the query against the document store with the expectation of a large set of results
|
||||
@@ -120,7 +120,7 @@ public interface DocumentStore {
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* server.find(Order.class)
|
||||
* database.find(Order.class)
|
||||
* .setUseDocStore(true)
|
||||
* .where()... // perhaps add predicates
|
||||
* .findEach((Order order) -> {
|
||||
@@ -129,7 +129,7 @@ public interface DocumentStore {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
<T> void findEach(DocQueryRequest<T> query, Consumer<T> consumer);
|
||||
<T> void findEach(DocQueryContext<T> query, Consumer<T> consumer);
|
||||
|
||||
/**
|
||||
* Execute the query against the document store with the expectation of a large set of results
|
||||
@@ -145,11 +145,11 @@ public interface DocumentStore {
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* server.find(Order.class)
|
||||
* database.find(Order.class)
|
||||
* .setUseDocStore(true)
|
||||
* .where()... // perhaps add predicates
|
||||
* .findEachWhile(new Predicate<Order>() {
|
||||
* @Override
|
||||
* @Override
|
||||
* public void accept(Order bean) {
|
||||
* // process the bean
|
||||
*
|
||||
@@ -161,7 +161,7 @@ public interface DocumentStore {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
<T> void findEachWhile(DocQueryRequest<T> query, Predicate<T> consumer);
|
||||
<T> void findEachWhile(DocQueryContext<T> query, Predicate<T> consumer);
|
||||
|
||||
/**
|
||||
* Find each processing raw documents.
|
||||
@@ -190,7 +190,7 @@ public interface DocumentStore {
|
||||
* Drop the index from the document store (similar to DDL drop table).
|
||||
* <pre>{@code
|
||||
*
|
||||
* DocumentStore documentStore = server.docStore();
|
||||
* DocumentStore documentStore = database.docStore();
|
||||
*
|
||||
* documentStore.dropIndex("product_copy");
|
||||
*
|
||||
@@ -202,7 +202,7 @@ public interface DocumentStore {
|
||||
* Create an index given a mapping file as a resource in the classPath (similar to DDL create table).
|
||||
* <pre>{@code
|
||||
*
|
||||
* DocumentStore documentStore = server.docStore();
|
||||
* DocumentStore documentStore = database.docStore();
|
||||
*
|
||||
* // uses product_copy.mapping.json resource
|
||||
* // ... to define mappings for the index
|
||||
@@ -289,7 +289,7 @@ public interface DocumentStore {
|
||||
* <pre>{@code
|
||||
*
|
||||
* // predicates to select the source documents to copy
|
||||
* Query<Product> query = server.find(Product.class)
|
||||
* Query<Product> query = database.find(Product.class)
|
||||
* .where()
|
||||
* .ge("whenModified", new Timestamp(since))
|
||||
* .ge("name", "A")
|
||||
+29
-2
@@ -77,12 +77,29 @@ public interface DtoQuery<T> {
|
||||
Optional<T> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
* The same as bind for named parameters.
|
||||
* Bind all the parameters using index positions.
|
||||
* <p>
|
||||
* Binds each parameter moving the index position each time.
|
||||
* <p>
|
||||
* A convenience for multiple calls to {@link #setParameter(Object)}
|
||||
*/
|
||||
DtoQuery<T> setParameters(Object... value);
|
||||
|
||||
/**
|
||||
* Bind the next parameter using index position.
|
||||
* <p>
|
||||
* Bind the parameter using index position starting at 1 and incrementing.
|
||||
* <p>
|
||||
*/
|
||||
DtoQuery<T> setParameter(Object value);
|
||||
|
||||
/**
|
||||
* Bind the named parameter.
|
||||
*/
|
||||
DtoQuery<T> setParameter(String name, Object value);
|
||||
|
||||
/**
|
||||
* The same as bind for positioned parameters.
|
||||
* Bind the parameter by its index position (1 based like JDBC).
|
||||
*/
|
||||
DtoQuery<T> setParameter(int position, Object value);
|
||||
|
||||
@@ -109,6 +126,12 @@ public interface DtoQuery<T> {
|
||||
*/
|
||||
DtoQuery<T> setLabel(String label);
|
||||
|
||||
/**
|
||||
* Set the profile location of this query. This is used to relate query execution metrics
|
||||
* back to a location like a specific line of code.
|
||||
*/
|
||||
DtoQuery<T> setProfileLocation(ProfileLocation profileLocation);
|
||||
|
||||
/**
|
||||
* Set a timeout on this query.
|
||||
* <p>
|
||||
@@ -130,4 +153,8 @@ public interface DtoQuery<T> {
|
||||
*/
|
||||
DtoQuery<T> setBufferFetchSizeHint(int bufferFetchSizeHint);
|
||||
|
||||
/**
|
||||
* Use the explicit transaction to execute the query.
|
||||
*/
|
||||
DtoQuery<T> usingTransaction(Transaction transaction);
|
||||
}
|
||||
@@ -2,152 +2,33 @@ package io.ebean;
|
||||
|
||||
import io.ebean.annotation.TxIsolation;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.config.BeanNotEnhancedException;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.datasource.DataSourceConfigurationException;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Deprecated - please migrate to use <code>io.ebean.DB</code>.
|
||||
* <p>
|
||||
* Ebean is a registry of {@link Database} by name. Ebean has now been renamed to {@link DB}.
|
||||
* <p>
|
||||
* Ebean is effectively this is an alias for {@link DB} which is the new and improved name for Ebean.
|
||||
* <p>
|
||||
* The preference is to use DB and Database rather than Ebean and EbeanServer.
|
||||
*/
|
||||
@Deprecated
|
||||
public final class Ebean {
|
||||
private static final Logger logger = LoggerFactory.getLogger(Ebean.class);
|
||||
|
||||
static {
|
||||
EbeanVersion.getVersion(); // initialises the version class and logs the version.
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages creation and cache of Databases.
|
||||
*/
|
||||
private static final Ebean.ServerManager serverMgr = new Ebean.ServerManager();
|
||||
|
||||
/**
|
||||
* Helper class for managing fast and safe access and creation of Databases.
|
||||
*/
|
||||
private static final class ServerManager {
|
||||
|
||||
/**
|
||||
* Cache for fast concurrent read access.
|
||||
*/
|
||||
private final ConcurrentHashMap<String, EbeanServer> concMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Cache for synchronized read, creation and put. Protected by the monitor object.
|
||||
*/
|
||||
private final HashMap<String, EbeanServer> syncMap = new HashMap<>();
|
||||
|
||||
private final Object monitor = new Object();
|
||||
|
||||
/**
|
||||
* The 'default' Database.
|
||||
*/
|
||||
private EbeanServer defaultServer;
|
||||
|
||||
private ServerManager() {
|
||||
|
||||
try {
|
||||
if (!PrimaryServer.isSkip()) {
|
||||
// look to see if there is a default server defined
|
||||
String defaultName = PrimaryServer.getDefaultServerName();
|
||||
logger.debug("defaultName:{}", defaultName);
|
||||
if (defaultName != null && !defaultName.trim().isEmpty()) {
|
||||
defaultServer = getWithCreate(defaultName.trim());
|
||||
}
|
||||
}
|
||||
} catch (BeanNotEnhancedException e) {
|
||||
throw e;
|
||||
|
||||
} catch (DataSourceConfigurationException e) {
|
||||
String msg = "Configuration error creating DataSource for the default Database." +
|
||||
" This typically means a missing application-test.yaml or missing ebean-test-config dependency." +
|
||||
" See https://ebean.io/docs/trouble-shooting#datasource";
|
||||
throw new DataSourceConfigurationException(msg, e);
|
||||
|
||||
} catch (Throwable e) {
|
||||
logger.error("Error trying to create the default Database", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private EbeanServer getDefaultServer() {
|
||||
if (defaultServer == null) {
|
||||
String msg = "The default Database has not been defined?";
|
||||
msg += " This is normally set via the ebean.datasource.default property.";
|
||||
msg += " Otherwise it should be registered programmatically via registerServer()";
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
return defaultServer;
|
||||
}
|
||||
|
||||
private EbeanServer get(String name) {
|
||||
if (name == null || name.isEmpty()) {
|
||||
return defaultServer;
|
||||
}
|
||||
// non-synchronized read
|
||||
EbeanServer server = concMap.get(name);
|
||||
if (server != null) {
|
||||
return server;
|
||||
}
|
||||
// synchronized read, create and put
|
||||
return getWithCreate(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronized read, create and put of Databases.
|
||||
*/
|
||||
private EbeanServer getWithCreate(String name) {
|
||||
|
||||
synchronized (monitor) {
|
||||
|
||||
EbeanServer server = syncMap.get(name);
|
||||
if (server == null) {
|
||||
// register when creating server this way
|
||||
server = EbeanServerFactory.create(name);
|
||||
register(server, false);
|
||||
}
|
||||
return server;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a server so we can get it by its name.
|
||||
*/
|
||||
private void register(EbeanServer server, boolean isDefaultServer) {
|
||||
registerWithName(server.getName(), server, isDefaultServer);
|
||||
}
|
||||
|
||||
private void registerWithName(String name, EbeanServer server, boolean isDefaultServer) {
|
||||
synchronized (monitor) {
|
||||
concMap.put(name, server);
|
||||
syncMap.put(name, server);
|
||||
if (isDefaultServer) {
|
||||
defaultServer = server;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private static final DbContext context = DbContext.getInstance();
|
||||
|
||||
private Ebean() {
|
||||
}
|
||||
@@ -171,7 +52,7 @@ public final class Ebean {
|
||||
* @param name the name of the server, can use null for the 'default server'
|
||||
*/
|
||||
public static EbeanServer getServer(String name) {
|
||||
return serverMgr.get(name);
|
||||
return (EbeanServer)context.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,11 +62,31 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static EbeanServer getDefaultServer() {
|
||||
return serverMgr.getDefaultServer();
|
||||
return (EbeanServer)context.getDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ExpressionFactory from the default server.
|
||||
* Register the server with this Ebean singleton. Specify if the registered
|
||||
* server is the primary/default database.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void register(EbeanServer server, boolean defaultServer) {
|
||||
context.register(server, defaultServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Backdoor for registering a mock implementation of EbeanServer as the default database.
|
||||
*/
|
||||
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
|
||||
return (EbeanServer)context.mock(name, server, defaultServer);
|
||||
}
|
||||
|
||||
private static Database getDefault() {
|
||||
return context.getDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ExpressionFactory from the default database.
|
||||
* <p>
|
||||
* The ExpressionFactory is used internally by the query and ExpressionList to
|
||||
* build the WHERE and HAVING clauses. Alternatively you can use the
|
||||
@@ -202,24 +103,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static ExpressionFactory getExpressionFactory() {
|
||||
return serverMgr.getDefaultServer().getExpressionFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the server with this Ebean singleton. Specify if the registered
|
||||
* server is the primary/default server.
|
||||
*/
|
||||
public static void register(EbeanServer server, boolean defaultServer) {
|
||||
serverMgr.register(server, defaultServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Backdoor for registering a mock implementation of EbeanServer as the default server.
|
||||
*/
|
||||
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
|
||||
EbeanServer originalPrimaryServer = serverMgr.defaultServer;
|
||||
serverMgr.registerWithName(name, server, defaultServer);
|
||||
return originalPrimaryServer;
|
||||
return getDefault().getExpressionFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,7 +119,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static Object nextId(Class<?> beanType) {
|
||||
return serverMgr.getDefaultServer().nextId(beanType);
|
||||
return getDefault().nextId(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,7 +165,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static Transaction beginTransaction() {
|
||||
return serverMgr.getDefaultServer().beginTransaction();
|
||||
return getDefault().beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,7 +174,7 @@ public final class Ebean {
|
||||
* @param isolation the Transaction isolation level
|
||||
*/
|
||||
public static Transaction beginTransaction(TxIsolation isolation) {
|
||||
return serverMgr.getDefaultServer().beginTransaction(isolation);
|
||||
return getDefault().beginTransaction(isolation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -343,7 +227,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static Transaction beginTransaction(TxScope scope) {
|
||||
return serverMgr.getDefaultServer().beginTransaction(scope);
|
||||
return getDefault().beginTransaction(scope);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -351,7 +235,7 @@ public final class Ebean {
|
||||
* in scope.
|
||||
*/
|
||||
public static Transaction currentTransaction() {
|
||||
return serverMgr.getDefaultServer().currentTransaction();
|
||||
return getDefault().currentTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -381,21 +265,21 @@ public final class Ebean {
|
||||
* @throws PersistenceException if there is no currently active transaction
|
||||
*/
|
||||
public static void register(TransactionCallback transactionCallback) throws PersistenceException {
|
||||
serverMgr.getDefaultServer().register(transactionCallback);
|
||||
getDefault().register(transactionCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
public static void commitTransaction() {
|
||||
serverMgr.getDefaultServer().commitTransaction();
|
||||
getDefault().commitTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback the current transaction.
|
||||
*/
|
||||
public static void rollbackTransaction() {
|
||||
serverMgr.getDefaultServer().rollbackTransaction();
|
||||
getDefault().rollbackTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -423,14 +307,14 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static void endTransaction() {
|
||||
serverMgr.getDefaultServer().endTransaction();
|
||||
getDefault().endTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the current transaction as rollback only.
|
||||
*/
|
||||
public static void setRollbackOnly() {
|
||||
serverMgr.getDefaultServer().currentTransaction().setRollbackOnly();
|
||||
getDefault().currentTransaction().setRollbackOnly();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -441,7 +325,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static Map<String, ValuePair> diff(Object a, Object b) {
|
||||
return serverMgr.getDefaultServer().diff(a, b);
|
||||
return getDefault().diff(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,7 +346,7 @@ public final class Ebean {
|
||||
* <pre>{@code
|
||||
* public class Order { ...
|
||||
*
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* List<OrderDetail> details;
|
||||
* ...
|
||||
* }
|
||||
@@ -475,7 +359,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static void save(Object bean) throws OptimisticLockException {
|
||||
serverMgr.getDefaultServer().save(bean);
|
||||
getDefault().save(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -483,14 +367,14 @@ public final class Ebean {
|
||||
* want to explicitly insert it.
|
||||
*/
|
||||
public static void insert(Object bean) {
|
||||
serverMgr.getDefaultServer().insert(bean);
|
||||
getDefault().insert(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a collection of beans.
|
||||
*/
|
||||
public static void insertAll(Collection<?> beans) {
|
||||
serverMgr.getDefaultServer().insertAll(beans);
|
||||
getDefault().insertAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -513,7 +397,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static void markAsDirty(Object bean) throws OptimisticLockException {
|
||||
serverMgr.getDefaultServer().markAsDirty(bean);
|
||||
getDefault().markAsDirty(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -528,16 +412,6 @@ public final class Ebean {
|
||||
* <b>Optimistic Locking: </b> Note that if the version property is not set when update() is
|
||||
* called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link ServerConfig#setUpdatesDeleteMissingChildren(boolean)}: </b> When cascade saving to a
|
||||
* OneToMany or ManyToMany the updatesDeleteMissingChildren setting controls if any other children
|
||||
* that are in the database but are not in the collection are deleted.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link ServerConfig#setUpdateChangesOnly(boolean)}: </b> The updateChangesOnly setting
|
||||
* controls if only the changed properties are included in the update or if all the loaded
|
||||
* properties are included instead.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // A 'stateless update' example
|
||||
@@ -548,19 +422,16 @@ public final class Ebean {
|
||||
* DB.update(customer);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see ServerConfig#setUpdatesDeleteMissingChildren(boolean)
|
||||
* @see ServerConfig#setUpdateChangesOnly(boolean)
|
||||
*/
|
||||
public static void update(Object bean) throws OptimisticLockException {
|
||||
serverMgr.getDefaultServer().update(bean);
|
||||
getDefault().update(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the beans in the collection.
|
||||
*/
|
||||
public static void updateAll(Collection<?> beans) throws OptimisticLockException {
|
||||
serverMgr.getDefaultServer().updateAll(beans);
|
||||
getDefault().updateAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -569,7 +440,7 @@ public final class Ebean {
|
||||
* @param bean The bean to merge
|
||||
*/
|
||||
public static void merge(Object bean) {
|
||||
serverMgr.getDefaultServer().merge(bean);
|
||||
getDefault().merge(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -579,14 +450,14 @@ public final class Ebean {
|
||||
* @param options The options to control the merge
|
||||
*/
|
||||
public static void merge(Object bean, MergeOptions options) {
|
||||
serverMgr.getDefaultServer().merge(bean, options);
|
||||
getDefault().merge(bean, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all the beans from a Collection.
|
||||
*/
|
||||
public static int saveAll(Collection<?> beans) throws OptimisticLockException {
|
||||
return serverMgr.getDefaultServer().saveAll(beans);
|
||||
return getDefault().saveAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -637,7 +508,7 @@ public final class Ebean {
|
||||
*/
|
||||
@Nonnull
|
||||
public static Set<Property> checkUniqueness(Object bean) {
|
||||
return serverMgr.getDefaultServer().checkUniqueness(bean);
|
||||
return getDefault().checkUniqueness(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -645,7 +516,7 @@ public final class Ebean {
|
||||
*/
|
||||
@Nonnull
|
||||
public static Set<Property> checkUniqueness(Object bean, Transaction transaction) {
|
||||
return serverMgr.getDefaultServer().checkUniqueness(bean, transaction);
|
||||
return getDefault().checkUniqueness(bean, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -668,56 +539,56 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static boolean delete(Object bean) throws OptimisticLockException {
|
||||
return serverMgr.getDefaultServer().delete(bean);
|
||||
return getDefault().delete(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the bean in permanent fashion (will not use soft delete).
|
||||
*/
|
||||
public static boolean deletePermanent(Object bean) throws OptimisticLockException {
|
||||
return serverMgr.getDefaultServer().deletePermanent(bean);
|
||||
return getDefault().deletePermanent(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the bean given its type and id.
|
||||
*/
|
||||
public static int delete(Class<?> beanType, Object id) {
|
||||
return serverMgr.getDefaultServer().delete(beanType, id);
|
||||
return getDefault().delete(beanType, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permanent the bean given its type and id.
|
||||
*/
|
||||
public static int deletePermanent(Class<?> beanType, Object id) {
|
||||
return serverMgr.getDefaultServer().deletePermanent(beanType, id);
|
||||
return getDefault().deletePermanent(beanType, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete several beans given their type and id values.
|
||||
*/
|
||||
public static int deleteAll(Class<?> beanType, Collection<?> ids) {
|
||||
return serverMgr.getDefaultServer().deleteAll(beanType, ids);
|
||||
return getDefault().deleteAll(beanType, ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permanent several beans given their type and id values.
|
||||
*/
|
||||
public static int deleteAllPermanent(Class<?> beanType, Collection<?> ids) {
|
||||
return serverMgr.getDefaultServer().deleteAllPermanent(beanType, ids);
|
||||
return getDefault().deleteAllPermanent(beanType, ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the beans in the Collection.
|
||||
*/
|
||||
public static int deleteAll(Collection<?> beans) throws OptimisticLockException {
|
||||
return serverMgr.getDefaultServer().deleteAll(beans);
|
||||
return getDefault().deleteAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permanent all the beans in the Collection (will not use soft delete).
|
||||
*/
|
||||
public static int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException {
|
||||
return serverMgr.getDefaultServer().deleteAllPermanent(beans);
|
||||
return getDefault().deleteAllPermanent(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -728,7 +599,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static void refresh(Object bean) {
|
||||
serverMgr.getDefaultServer().refresh(bean);
|
||||
getDefault().refresh(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -746,7 +617,7 @@ public final class Ebean {
|
||||
* @param manyPropertyName the property name of the List Set or Map to refresh.
|
||||
*/
|
||||
public static void refreshMany(Object bean, String manyPropertyName) {
|
||||
serverMgr.getDefaultServer().refreshMany(bean, manyPropertyName);
|
||||
getDefault().refreshMany(bean, manyPropertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -771,7 +642,7 @@ public final class Ebean {
|
||||
* @param id the id value
|
||||
*/
|
||||
public static <T> T getReference(Class<T> beanType, Object id) {
|
||||
return serverMgr.getDefaultServer().getReference(beanType, id);
|
||||
return getDefault().getReference(beanType, id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -797,7 +668,7 @@ public final class Ebean {
|
||||
* // find orders and their customers
|
||||
* List<Order> list = Ebean.find(Order.class)
|
||||
* .fetch("customer")
|
||||
* .orderBy("id")
|
||||
* .order("id")
|
||||
* .findList();
|
||||
*
|
||||
* // sort by customer name ascending, then by order shipDate
|
||||
@@ -814,7 +685,7 @@ public final class Ebean {
|
||||
* @param sortByClause the properties to sort the list by
|
||||
*/
|
||||
public static <T> void sort(List<T> list, String sortByClause) {
|
||||
serverMgr.getDefaultServer().sort(list, sortByClause);
|
||||
getDefault().sort(list, sortByClause);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -864,10 +735,12 @@ public final class Ebean {
|
||||
*/
|
||||
@Nullable
|
||||
public static <T> T find(Class<T> beanType, Object id) {
|
||||
return serverMgr.getDefaultServer().find(beanType, id);
|
||||
return getDefault().find(beanType, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to DB.sqlQuery().
|
||||
* <p>
|
||||
* Create a SqlQuery for executing native sql
|
||||
* query statements.
|
||||
* <p>
|
||||
@@ -875,22 +748,24 @@ public final class Ebean {
|
||||
* annotation for examples.
|
||||
* </p>
|
||||
*/
|
||||
@Deprecated
|
||||
public static SqlQuery createSqlQuery(String sql) {
|
||||
return serverMgr.getDefaultServer().createSqlQuery(sql);
|
||||
return getDefault().sqlQuery(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to DB.sqlUpdate().
|
||||
* <p>
|
||||
* Create a sql update for executing native dml statements.
|
||||
* <p>
|
||||
* Use this to execute a Insert Update or Delete statement. The statement will
|
||||
* be native to the database and contain database table and column names.
|
||||
* </p>
|
||||
* <p>
|
||||
* See {@link SqlUpdate} for example usage.
|
||||
* </p>
|
||||
*/
|
||||
@Deprecated
|
||||
public static SqlUpdate createSqlUpdate(String sql) {
|
||||
return serverMgr.getDefaultServer().createSqlUpdate(sql);
|
||||
return getDefault().sqlUpdate(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -899,7 +774,7 @@ public final class Ebean {
|
||||
* @see CallableSql
|
||||
*/
|
||||
public static CallableSql createCallableSql(String sql) {
|
||||
return serverMgr.getDefaultServer().createCallableSql(sql);
|
||||
return getDefault().createCallableSql(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -931,16 +806,14 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) {
|
||||
|
||||
return serverMgr.getDefaultServer().createUpdate(beanType, ormUpdate);
|
||||
return getDefault().createUpdate(beanType, ormUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CsvReader for a given beanType.
|
||||
*/
|
||||
public static <T> CsvReader<T> createCsvReader(Class<T> beanType) {
|
||||
|
||||
return serverMgr.getDefaultServer().createCsvReader(beanType);
|
||||
return getDefault().createCsvReader(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -955,7 +828,7 @@ public final class Ebean {
|
||||
* @return The query
|
||||
*/
|
||||
public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
|
||||
return serverMgr.getDefaultServer().createNamedQuery(beanType, namedQuery);
|
||||
return getDefault().createNamedQuery(beanType, namedQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -978,8 +851,7 @@ public final class Ebean {
|
||||
* @return A ORM Query object for this beanType
|
||||
*/
|
||||
public static <T> Query<T> createQuery(Class<T> beanType) {
|
||||
|
||||
return serverMgr.getDefaultServer().createQuery(beanType);
|
||||
return getDefault().createQuery(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1016,8 +888,7 @@ public final class Ebean {
|
||||
* @return The query with expressions defined as per the parsed query statement
|
||||
*/
|
||||
public static <T> Query<T> createQuery(Class<T> beanType, String eql) {
|
||||
|
||||
return serverMgr.getDefaultServer().createQuery(beanType, eql);
|
||||
return getDefault().createQuery(beanType, eql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1032,8 +903,7 @@ public final class Ebean {
|
||||
* @return A ORM Query object for this beanType
|
||||
*/
|
||||
public static <T> Query<T> find(Class<T> beanType) {
|
||||
|
||||
return serverMgr.getDefaultServer().find(beanType);
|
||||
return getDefault().find(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1056,7 +926,7 @@ public final class Ebean {
|
||||
* @return The query to set parameters and execute
|
||||
*/
|
||||
public static <T> Query<T> findNative(Class<T> beanType, String nativeSql) {
|
||||
return serverMgr.getDefaultServer().findNative(beanType, nativeSql);
|
||||
return getDefault().findNative(beanType, nativeSql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1071,7 +941,7 @@ public final class Ebean {
|
||||
* @param <T> The type of the DTO bean.
|
||||
*/
|
||||
public static <T> DtoQuery<T> findDto(Class<T> dtoType, String sql) {
|
||||
return serverMgr.getDefaultServer().findDto(dtoType, sql);
|
||||
return getDefault().findDto(dtoType, sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1093,7 +963,7 @@ public final class Ebean {
|
||||
* @return The update query to use
|
||||
*/
|
||||
public static <T> UpdateQuery<T> update(Class<T> beanType) {
|
||||
return serverMgr.getDefaultServer().update(beanType);
|
||||
return getDefault().update(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1107,7 +977,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static <T> Filter<T> filter(Class<T> beanType) {
|
||||
return serverMgr.getDefaultServer().filter(beanType);
|
||||
return getDefault().filter(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1150,7 +1020,7 @@ public final class Ebean {
|
||||
* @see Ebean#execute(CallableSql)
|
||||
*/
|
||||
public static int execute(SqlUpdate sqlUpdate) {
|
||||
return serverMgr.getDefaultServer().execute(sqlUpdate);
|
||||
return getDefault().execute(sqlUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1178,7 +1048,7 @@ public final class Ebean {
|
||||
* @see Ebean#execute(SqlUpdate)
|
||||
*/
|
||||
public static int execute(CallableSql callableSql) {
|
||||
return serverMgr.getDefaultServer().execute(callableSql);
|
||||
return getDefault().execute(callableSql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1196,13 +1066,13 @@ public final class Ebean {
|
||||
* public void run() {
|
||||
* User u1 = Ebean.find(User.class, 1);
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public static void execute(TxScope scope, Runnable r) {
|
||||
serverMgr.getDefaultServer().execute(scope, r);
|
||||
getDefault().execute(scope, r);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1229,7 +1099,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static void execute(Runnable r) {
|
||||
serverMgr.getDefaultServer().execute(r);
|
||||
getDefault().execute(r);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1248,13 +1118,13 @@ public final class Ebean {
|
||||
* User u1 = Ebean.find(User.class, 1);
|
||||
* ...
|
||||
* return u1.getEmail();
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public static <T> T executeCall(TxScope scope, Callable<T> c) {
|
||||
return serverMgr.getDefaultServer().executeCall(scope, c);
|
||||
return getDefault().executeCall(scope, c);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1287,7 +1157,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static <T> T executeCall(Callable<T> c) {
|
||||
return serverMgr.getDefaultServer().executeCall(c);
|
||||
return getDefault().executeCall(c);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1321,8 +1191,7 @@ public final class Ebean {
|
||||
* @param deletes true if rows on the table where deleted
|
||||
*/
|
||||
public static void externalModification(String tableName, boolean inserts, boolean updates, boolean deletes) {
|
||||
|
||||
serverMgr.getDefaultServer().externalModification(tableName, inserts, updates, deletes);
|
||||
getDefault().externalModification(tableName, inserts, updates, deletes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1332,14 +1201,14 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static BeanState getBeanState(Object bean) {
|
||||
return serverMgr.getDefaultServer().getBeanState(bean);
|
||||
return getDefault().getBeanState(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the manager of the server cache ("L2" cache).
|
||||
*/
|
||||
public static ServerCacheManager getServerCacheManager() {
|
||||
return serverMgr.getDefaultServer().getServerCacheManager();
|
||||
return getDefault().getServerCacheManager();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1347,14 +1216,14 @@ public final class Ebean {
|
||||
* queries.
|
||||
*/
|
||||
public static BackgroundExecutor getBackgroundExecutor() {
|
||||
return serverMgr.getDefaultServer().getBackgroundExecutor();
|
||||
return getDefault().getBackgroundExecutor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JsonContext for reading/writing JSON.
|
||||
*/
|
||||
public static JsonContext json() {
|
||||
return serverMgr.getDefaultServer().json();
|
||||
return getDefault().json();
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -1,6 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
/**
|
||||
* Deprecated - please migrate to <code>io.ebean.Database</code>.
|
||||
* Provides the API for fetching and saving beans to a particular Database.
|
||||
* <p>
|
||||
* Effectively this is an alias for {@link Database} which is now the new
|
||||
@@ -8,6 +9,7 @@ package io.ebean;
|
||||
* <p>
|
||||
* The preference is to use DB and Database rather than Ebean and EbeanServer.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface EbeanServer extends Database {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.config.ContainerConfig;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.service.SpiContainer;
|
||||
import io.ebean.service.SpiContainerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Deprecated - please migrate to DatabaseFactory.
|
||||
* <p>
|
||||
* Creates EbeanServer instances.
|
||||
* <p>
|
||||
* This uses either a ServerConfig or properties in the ebean.properties file to
|
||||
* configure and create a EbeanServer instance.
|
||||
* </p>
|
||||
* <p>
|
||||
* The EbeanServer instance can either be registered with the Ebean singleton or
|
||||
* not. The Ebean singleton effectively holds a map of EbeanServers by a name.
|
||||
* If the EbeanServer is registered with the Ebean singleton you can retrieve it
|
||||
* later via {@link Ebean#getServer(String)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* One EbeanServer can be nominated as the 'default/primary' EbeanServer. Many
|
||||
* methods on the Ebean singleton such as {@link Ebean#find(Class)} are just a
|
||||
* convenient way of using the 'default/primary' EbeanServer.
|
||||
* </p>
|
||||
*/
|
||||
@Deprecated
|
||||
public class EbeanServerFactory {
|
||||
|
||||
/**
|
||||
* Initialise the container with clustering configuration.
|
||||
* <p>
|
||||
* Call this prior to creating any EbeanServer instances or alternatively set the
|
||||
* ContainerConfig on the ServerConfig when creating the first EbeanServer instance.
|
||||
*/
|
||||
public static void initialiseContainer(ContainerConfig containerConfig) {
|
||||
DatabaseFactory.initialiseContainer(containerConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using ebean.properties to configure the database.
|
||||
*/
|
||||
public static EbeanServer create(String name) {
|
||||
return (EbeanServer)DatabaseFactory.create(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the ServerConfig object to configure the database.
|
||||
*/
|
||||
public static EbeanServer create(ServerConfig config) {
|
||||
return (EbeanServer)DatabaseFactory.create(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the ServerConfig additionally specifying a classLoader to use as the context class loader.
|
||||
*/
|
||||
public static EbeanServer createWithContextClassLoader(ServerConfig config, ClassLoader classLoader) {
|
||||
return (EbeanServer)DatabaseFactory.createWithContextClassLoader(config, classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown gracefully all EbeanServers cleaning up any resources as required.
|
||||
* <p>
|
||||
* This is typically invoked via JVM shutdown hook and not explicitly called.
|
||||
* </p>
|
||||
*/
|
||||
public static void shutdown() {
|
||||
DatabaseFactory.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
+9
-5
@@ -6,22 +6,22 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Class to determine the ebean version. (
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
* Class to determine the ebean version.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*/
|
||||
public class EbeanVersion {
|
||||
private EbeanVersion() {
|
||||
|
||||
}
|
||||
private static final Logger logger = LoggerFactory.getLogger(EbeanVersion.class);
|
||||
|
||||
private static String version = "unknown";
|
||||
|
||||
static {
|
||||
try {
|
||||
Properties prop = new Properties();
|
||||
try (InputStream in = Ebean.class.getResourceAsStream("/META-INF/maven/io.ebean/ebean/pom.properties")) {
|
||||
try (InputStream in = DB.class.getResourceAsStream("/META-INF/maven/io.ebean/ebean/pom.properties")) {
|
||||
if (in != null) {
|
||||
prop.load(in);
|
||||
in.close();
|
||||
@@ -34,6 +34,10 @@ public class EbeanVersion {
|
||||
}
|
||||
}
|
||||
|
||||
private EbeanVersion() {
|
||||
// hide
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ebean version (read from /META-INF/maven/io.ebean/ebean/pom.properties)
|
||||
*/
|
||||
@@ -0,0 +1,74 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* An empty PagedList.
|
||||
* <p>
|
||||
* For use in application code when we need to return a PagedList but don't want to
|
||||
* execute a query.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* PagedList<Customer> empty = PagedList.emptyList();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public class EmptyPagedList<T> implements PagedList<T> {
|
||||
|
||||
@Override
|
||||
public void loadCount() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Future<Integer> getFutureCount() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<T> getList() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalPageCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPageSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPageIndex() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrev() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayXtoYofZ(String to, String of) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -34,14 +34,14 @@ public class Expr {
|
||||
* Equal To - property equal to the given value.
|
||||
*/
|
||||
public static Expression eq(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().eq(propertyName, value);
|
||||
return DB.getExpressionFactory().eq(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Equal To - property not equal to the given value.
|
||||
*/
|
||||
public static Expression ne(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().ne(propertyName, value);
|
||||
return DB.getExpressionFactory().ne(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,38 +49,38 @@ public class Expr {
|
||||
* using a lower() function to make it case insensitive).
|
||||
*/
|
||||
public static Expression ieq(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().ieq(propertyName, value);
|
||||
return DB.getExpressionFactory().ieq(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* In Range - property >= value1 and property < value2.
|
||||
* In Range - {@code property >= value1 and property < value2}.
|
||||
* <p>
|
||||
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
|
||||
* </p>
|
||||
*/
|
||||
public static Expression inRange(String propertyName, Object value1, Object value2) {
|
||||
return Ebean.getExpressionFactory().inRange(propertyName, value1, value2);
|
||||
return DB.getExpressionFactory().inRange(propertyName, value1, value2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Between - property between the two given values.
|
||||
*/
|
||||
public static Expression between(String propertyName, Object value1, Object value2) {
|
||||
return Ebean.getExpressionFactory().between(propertyName, value1, value2);
|
||||
return DB.getExpressionFactory().between(propertyName, value1, value2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Between - value between two given properties.
|
||||
*/
|
||||
public static Expression between(String lowProperty, String highProperty, Object value) {
|
||||
return Ebean.getExpressionFactory().betweenProperties(lowProperty, highProperty, value);
|
||||
return DB.getExpressionFactory().betweenProperties(lowProperty, highProperty, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater Than - property greater than the given value.
|
||||
*/
|
||||
public static Expression gt(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().gt(propertyName, value);
|
||||
return DB.getExpressionFactory().gt(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,42 +88,42 @@ public class Expr {
|
||||
* value.
|
||||
*/
|
||||
public static Expression ge(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().ge(propertyName, value);
|
||||
return DB.getExpressionFactory().ge(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less Than - property less than the given value.
|
||||
*/
|
||||
public static Expression lt(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().lt(propertyName, value);
|
||||
return DB.getExpressionFactory().lt(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less Than or Equal to - property less than or equal to the given value.
|
||||
*/
|
||||
public static Expression le(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().le(propertyName, value);
|
||||
return DB.getExpressionFactory().le(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Null - property is null.
|
||||
*/
|
||||
public static Expression isNull(String propertyName) {
|
||||
return Ebean.getExpressionFactory().isNull(propertyName);
|
||||
return DB.getExpressionFactory().isNull(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Not Null - property is not null.
|
||||
*/
|
||||
public static Expression isNotNull(String propertyName) {
|
||||
return Ebean.getExpressionFactory().isNotNull(propertyName);
|
||||
return DB.getExpressionFactory().isNotNull(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive {@link #exampleLike(Object)}
|
||||
*/
|
||||
public static ExampleExpression iexampleLike(Object example) {
|
||||
return Ebean.getExpressionFactory().iexampleLike(example);
|
||||
return DB.getExpressionFactory().iexampleLike(example);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,14 +131,14 @@ public class Expr {
|
||||
* LikeType.RAW (you need to add you own wildcards % and _).
|
||||
*/
|
||||
public static ExampleExpression exampleLike(Object example) {
|
||||
return Ebean.getExpressionFactory().exampleLike(example);
|
||||
return DB.getExpressionFactory().exampleLike(example);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the query by Example expression specifying more options.
|
||||
*/
|
||||
public static ExampleExpression exampleLike(Object example, boolean caseInsensitive, LikeType likeType) {
|
||||
return Ebean.getExpressionFactory().exampleLike(example, caseInsensitive, likeType);
|
||||
return DB.getExpressionFactory().exampleLike(example, caseInsensitive, likeType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,7 +146,7 @@ public class Expr {
|
||||
* characters % (percentage) and _ (underscore).
|
||||
*/
|
||||
public static Expression like(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().like(propertyName, value);
|
||||
return DB.getExpressionFactory().like(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,14 +155,14 @@ public class Expr {
|
||||
* a lower() function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression ilike(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().ilike(propertyName, value);
|
||||
return DB.getExpressionFactory().ilike(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts With - property like value%.
|
||||
*/
|
||||
public static Expression startsWith(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().startsWith(propertyName, value);
|
||||
return DB.getExpressionFactory().startsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,14 +170,14 @@ public class Expr {
|
||||
* lower() function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression istartsWith(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().istartsWith(propertyName, value);
|
||||
return DB.getExpressionFactory().istartsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends With - property like %value.
|
||||
*/
|
||||
public static Expression endsWith(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().endsWith(propertyName, value);
|
||||
return DB.getExpressionFactory().endsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,14 +185,14 @@ public class Expr {
|
||||
* function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression iendsWith(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().iendsWith(propertyName, value);
|
||||
return DB.getExpressionFactory().iendsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains - property like %value%.
|
||||
*/
|
||||
public static Expression contains(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().contains(propertyName, value);
|
||||
return DB.getExpressionFactory().contains(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,42 +200,42 @@ public class Expr {
|
||||
* function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression icontains(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().icontains(propertyName, value);
|
||||
return DB.getExpressionFactory().icontains(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* For collection properties that are empty (have not existing elements).
|
||||
*/
|
||||
public static Expression isEmpty(String propertyName) {
|
||||
return Ebean.getExpressionFactory().isEmpty(propertyName);
|
||||
return DB.getExpressionFactory().isEmpty(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* For collection properties that are not empty (have existing elements).
|
||||
*/
|
||||
public static Expression isNotEmpty(String propertyName) {
|
||||
return Ebean.getExpressionFactory().isNotEmpty(propertyName);
|
||||
return DB.getExpressionFactory().isNotEmpty(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - property has a value in the array of values.
|
||||
*/
|
||||
public static Expression in(String propertyName, Object[] values) {
|
||||
return Ebean.getExpressionFactory().in(propertyName, values);
|
||||
return DB.getExpressionFactory().in(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - using a subQuery.
|
||||
*/
|
||||
public static Expression in(String propertyName, Query<?> subQuery) {
|
||||
return Ebean.getExpressionFactory().in(propertyName, subQuery);
|
||||
return DB.getExpressionFactory().in(propertyName, subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - property has a value in the collection of values.
|
||||
*/
|
||||
public static Expression in(String propertyName, Collection<?> values) {
|
||||
return Ebean.getExpressionFactory().in(propertyName, values);
|
||||
return DB.getExpressionFactory().in(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,14 +272,14 @@ public class Expr {
|
||||
* }</pre>
|
||||
*/
|
||||
public static Expression inOrEmpty(String propertyName, Collection<?> values) {
|
||||
return Ebean.getExpressionFactory().inOrEmpty(propertyName, values);
|
||||
return DB.getExpressionFactory().inOrEmpty(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Id Equal to - ID property is equal to the value.
|
||||
*/
|
||||
public static Expression idEq(Object value) {
|
||||
return Ebean.getExpressionFactory().idEq(value);
|
||||
return DB.getExpressionFactory().idEq(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,7 +292,7 @@ public class Expr {
|
||||
* @param propertyMap a map keyed by property names.
|
||||
*/
|
||||
public static Expression allEq(Map<String, Object> propertyMap) {
|
||||
return Ebean.getExpressionFactory().allEq(propertyMap);
|
||||
return DB.getExpressionFactory().allEq(propertyMap);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,7 +303,7 @@ public class Expr {
|
||||
* </p>
|
||||
*/
|
||||
public static Expression raw(String raw, Object value) {
|
||||
return Ebean.getExpressionFactory().raw(raw, value);
|
||||
return DB.getExpressionFactory().raw(raw, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,14 +314,14 @@ public class Expr {
|
||||
* </p>
|
||||
*/
|
||||
public static Expression raw(String raw, Object[] values) {
|
||||
return Ebean.getExpressionFactory().raw(raw, values);
|
||||
return DB.getExpressionFactory().raw(raw, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add raw expression with no parameters.
|
||||
*/
|
||||
public static Expression raw(String raw) {
|
||||
return Ebean.getExpressionFactory().raw(raw);
|
||||
return DB.getExpressionFactory().raw(raw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -329,7 +329,7 @@ public class Expr {
|
||||
*/
|
||||
public static Expression and(Expression expOne, Expression expTwo) {
|
||||
|
||||
return Ebean.getExpressionFactory().and(expOne, expTwo);
|
||||
return DB.getExpressionFactory().and(expOne, expTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,7 +337,7 @@ public class Expr {
|
||||
*/
|
||||
public static Expression or(Expression expOne, Expression expTwo) {
|
||||
|
||||
return Ebean.getExpressionFactory().or(expOne, expTwo);
|
||||
return DB.getExpressionFactory().or(expOne, expTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,7 +345,7 @@ public class Expr {
|
||||
*/
|
||||
public static Expression not(Expression exp) {
|
||||
|
||||
return Ebean.getExpressionFactory().not(exp);
|
||||
return DB.getExpressionFactory().not(exp);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -353,7 +353,7 @@ public class Expr {
|
||||
*/
|
||||
public static <T> Junction<T> conjunction(Query<T> query) {
|
||||
|
||||
return Ebean.getExpressionFactory().conjunction(query);
|
||||
return DB.getExpressionFactory().conjunction(query);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,6 +361,6 @@ public class Expr {
|
||||
*/
|
||||
public static <T> Junction<T> disjunction(Query<T> query) {
|
||||
|
||||
return Ebean.getExpressionFactory().disjunction(query);
|
||||
return DB.getExpressionFactory().disjunction(query);
|
||||
}
|
||||
}
|
||||
+25
-1
@@ -155,7 +155,7 @@ public interface ExpressionFactory {
|
||||
Expression ineObject(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* In Range - property >= value1 and property < value2.
|
||||
* In Range - {@code property >= value1 and property < value2}.
|
||||
* <p>
|
||||
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
|
||||
* </p>
|
||||
@@ -199,6 +199,14 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
Expression gtOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Greater than or Equal to OR Null <code> >= or null </code>
|
||||
* <p>
|
||||
* A convenient expression combining GE and Is Null. Most often useful for range
|
||||
* expressions where the top range value is nullable.
|
||||
*/
|
||||
Expression geOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Greater Than - property greater than the given value.
|
||||
*/
|
||||
@@ -218,6 +226,14 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
Expression ltOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Less Than or Equal to OR Null <code> <= or null </code>
|
||||
* <p>
|
||||
* A convenient expression combining LE and Is Null. Most often useful for range
|
||||
* expressions where the bottom range value is nullable.
|
||||
*/
|
||||
Expression leOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Less Than - property less than the given value.
|
||||
*/
|
||||
@@ -536,4 +552,12 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
<T> Junction<T> junction(Junction.Type type, Query<T> query, ExpressionList<T> parent);
|
||||
|
||||
/**
|
||||
* Add the expressions to the given expression list.
|
||||
*
|
||||
* @param where The expression list to add the expressions to
|
||||
* @param expressions The expressions that are parsed
|
||||
* @param params Bind parameters to match ? or ?1 bind positions.
|
||||
*/
|
||||
<T> void where(ExpressionList<T> where, String expressions, Object[] params);
|
||||
}
|
||||
+118
-42
@@ -9,6 +9,7 @@ import io.ebean.search.TextSimple;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -29,7 +30,7 @@ import java.util.function.Predicate;
|
||||
* </p>
|
||||
* <p>
|
||||
* The ExpressionList also duplicates methods that are found on the Query such
|
||||
* as findList() and orderBy(). The purpose of these methods is provide a fluid
|
||||
* as findList() and order(). The purpose of these methods is provide a fluid
|
||||
* API. The upside of this approach is that you can build and execute a query
|
||||
* via chained methods. The down side is that this ExpressionList object has
|
||||
* more methods than you would initially expect (the ones duplicated from
|
||||
@@ -51,6 +52,14 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
Query<T> query();
|
||||
|
||||
/**
|
||||
* Controls, if paginated queries should always append an 'order by id' statement at the end to
|
||||
* guarantee a deterministic sort result. This may affect performance.
|
||||
* If this is not enabled, and an orderBy is set on the query, it's up to the programmer that
|
||||
* this query provides a deterministic result.
|
||||
*/
|
||||
Query<T> orderById(boolean orderById);
|
||||
|
||||
/**
|
||||
* Set the order by clause replacing the existing order by clause if there is
|
||||
* one.
|
||||
@@ -58,12 +67,18 @@ public interface ExpressionList<T> {
|
||||
* This follows SQL syntax using commas between each property with the
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #orderBy(String)}.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> order(String orderByClause);
|
||||
ExpressionList<T> order(String orderByClause);
|
||||
|
||||
/**
|
||||
* Set the order by clause replacing the existing order by clause if there is
|
||||
* one.
|
||||
* <p>
|
||||
* This follows SQL syntax using commas between each property with the
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
*/
|
||||
ExpressionList<T> orderBy(String orderBy);
|
||||
|
||||
/**
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
@@ -71,7 +86,8 @@ public interface ExpressionList<T> {
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is the same as <code>orderBy()</code>
|
||||
*/
|
||||
OrderBy<T> order();
|
||||
|
||||
@@ -81,22 +97,15 @@ public interface ExpressionList<T> {
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is the same as <code>order()</code>
|
||||
*/
|
||||
OrderBy<T> orderBy();
|
||||
|
||||
/**
|
||||
* Add an orderBy clause to the query.
|
||||
*
|
||||
* @see Query#orderBy(String)
|
||||
*/
|
||||
Query<T> orderBy(String orderBy);
|
||||
|
||||
/**
|
||||
* Add an orderBy clause to the query.
|
||||
*
|
||||
* @see Query#orderBy(String)
|
||||
* Deprecated migrate to {@link #orderBy(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
Query<T> setOrderBy(String orderBy);
|
||||
|
||||
/**
|
||||
@@ -186,6 +195,16 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
Query<T> setIncludeSoftDeletes();
|
||||
|
||||
/**
|
||||
* Execute the query using the given transaction.
|
||||
*/
|
||||
Query<T> usingTransaction(Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query using the given connection.
|
||||
*/
|
||||
Query<T> usingConnection(Connection connection);
|
||||
|
||||
/**
|
||||
* Execute as a delete query deleting the 'root level' beans that match the predicates
|
||||
* in the query.
|
||||
@@ -323,7 +342,7 @@ public interface ExpressionList<T> {
|
||||
* List<String> names =
|
||||
* DB.find(Customer.class)
|
||||
* .select("name")
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -336,7 +355,7 @@ public interface ExpressionList<T> {
|
||||
* .setDistinct(true)
|
||||
* .select("name")
|
||||
* .where().eq("status", Customer.Status.NEW)
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .setMaxRows(100)
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
@@ -478,7 +497,26 @@ public interface ExpressionList<T> {
|
||||
* Add some filter predicate expressions to the many property.
|
||||
*/
|
||||
@Nonnull
|
||||
ExpressionList<T> filterMany(String prop);
|
||||
ExpressionList<T> filterMany(String manyProperty);
|
||||
|
||||
/**
|
||||
* Add filter expressions to the many property.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* DB.find(Customer.class)
|
||||
* .where()
|
||||
* .eq("name", "Rob")
|
||||
* .filterMany("orders", "status = ?", Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param manyProperty The many property
|
||||
* @param expressions Filter expressions with and, or and ? or ?1 type bind parameters
|
||||
* @param params Bind parameters used in the expressions
|
||||
*/
|
||||
ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params);
|
||||
|
||||
/**
|
||||
* Specify specific properties to fetch on the main/root bean (aka partial
|
||||
@@ -529,14 +567,14 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @see Query#setFirstRow(int)
|
||||
*/
|
||||
Query<T> setFirstRow(int firstRow);
|
||||
ExpressionList<T> setFirstRow(int firstRow);
|
||||
|
||||
/**
|
||||
* Set the maximum number of rows to fetch.
|
||||
*
|
||||
* @see Query#setMaxRows(int)
|
||||
*/
|
||||
Query<T> setMaxRows(int maxRows);
|
||||
ExpressionList<T> setMaxRows(int maxRows);
|
||||
|
||||
/**
|
||||
* Set the name of the property which values become the key of a map.
|
||||
@@ -652,6 +690,14 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> where();
|
||||
|
||||
/**
|
||||
* Add the expressions to this expression list.
|
||||
*
|
||||
* @param expressions The expressions that are parsed and added to this expression list
|
||||
* @param params Bind parameters to match ? or ?1 bind positions.
|
||||
*/
|
||||
ExpressionList<T> where(String expressions, Object... params);
|
||||
|
||||
/**
|
||||
* Path exists - for the given path in a JSON document.
|
||||
* <pre>{@code
|
||||
@@ -813,16 +859,16 @@ public interface ExpressionList<T> {
|
||||
ExpressionList<T> inRangeWith(String lowProperty, String highProperty, Object value);
|
||||
|
||||
/**
|
||||
* In Range - property >= value1 and property < value2.
|
||||
* In Range - {@code property >= value1 and property < value2}.
|
||||
* <p>
|
||||
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
|
||||
* </p>
|
||||
*/
|
||||
ExpressionList<T> inRange(String propertyName, Object value1, Object value2);
|
||||
|
||||
/**
|
||||
* Between - property between the two given values.
|
||||
*/
|
||||
/**
|
||||
* Between - property between the two given values.
|
||||
*/
|
||||
ExpressionList<T> between(String propertyName, Object value1, Object value2);
|
||||
|
||||
/**
|
||||
@@ -840,6 +886,11 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> gtOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Greater Than or Equal to OR Null - <code> >= or null </code>.
|
||||
*/
|
||||
ExpressionList<T> geOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Greater Than or Equal to - property greater than or equal to the given
|
||||
* value.
|
||||
@@ -856,6 +907,11 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> ltOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Less Than or Equal to OR Null - <code> <= or null </code>.
|
||||
*/
|
||||
ExpressionList<T> leOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Less Than or Equal to - property less than or equal to the given value.
|
||||
*/
|
||||
@@ -1205,26 +1261,35 @@ public interface ExpressionList<T> {
|
||||
/**
|
||||
* Add raw expression with a single parameter.
|
||||
* <p>
|
||||
* The raw expression should contain a single ? at the location of the
|
||||
* parameter.
|
||||
* </p>
|
||||
* The raw expression should contain a single ? or ?1
|
||||
* at the location of the parameter. We use ?1 when binding a
|
||||
* collection for an IN expression.
|
||||
* <p>
|
||||
* When properties in the clause are fully qualified as table-column names
|
||||
* then they are not translated. logical property name names (not fully
|
||||
* qualified) will still be translated to their physical name.
|
||||
* </p>
|
||||
* <p>
|
||||
* <h4>Example:</h4>
|
||||
* <h4>Examples:</h4>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // use a database function
|
||||
* raw("add_days(orderDate, 10) < ?", someDate)
|
||||
*
|
||||
* raw("name like ?", "Rob%")
|
||||
*
|
||||
* raw("name in (?1)", asList("Rob", "Fiona", "Jack"))
|
||||
*
|
||||
* raw("name = any(?)", asList("Rob", "Fiona", "Jack"))
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h4>Subquery example:</h4>
|
||||
* <h4>Subquery examples:</h4>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // Bind collection using ?1
|
||||
* .raw("id in (select c.id from o_customer c where c.name in (?1))", asList("Rob", "Fiona", "Jack"))
|
||||
*
|
||||
* // Using Postgres ANY expression
|
||||
* .raw("t0.customer_id in (select customer_id from customer_group where group_id = any(?::uuid[]))", groupIds)
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1234,14 +1299,25 @@ public interface ExpressionList<T> {
|
||||
/**
|
||||
* Add raw expression with an array of parameters.
|
||||
* <p>
|
||||
* The raw expression should contain the same number of ? as there are
|
||||
* parameters.
|
||||
* </p>
|
||||
* The raw expression should contain the same number of ? or ?1, ?2 ... bind parameters
|
||||
* as there are values. We use ?1, ?2 etc when binding a collection for an IN expression.
|
||||
* <p>
|
||||
* When properties in the clause are fully qualified as table-column names
|
||||
* then they are not translated. logical property name names (not fully
|
||||
* qualified) will still be translated to their physical name.
|
||||
* </p>
|
||||
*
|
||||
* <h4>Examples:</h4>
|
||||
* <pre>{@code
|
||||
*
|
||||
* raw("unitPrice > ? and product.id > ?", 2, 3)
|
||||
*
|
||||
* raw("(status = ? or (orderDate < ? and shipDate is null) or customer.name like ?)",
|
||||
* Order.Status.APPROVED,
|
||||
* new Timestamp(System.currentTimeMillis()),
|
||||
* "Rob")
|
||||
*
|
||||
* }</pre></pre>
|
||||
*/
|
||||
ExpressionList<T> raw(String raw, Object... values);
|
||||
|
||||
@@ -1316,7 +1392,7 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Note that we need to cast the Postgres array for UUID types like:
|
||||
* Note that we need to cast the Postgres array for UUID types like:
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -1324,7 +1400,7 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param raw The raw expression that is typically a subquery
|
||||
* @param raw The raw expression that is typically a subquery
|
||||
* @param values The values which is typically a list or set of id values.
|
||||
*/
|
||||
ExpressionList<T> rawOrEmpty(String raw, Collection<?> values);
|
||||
@@ -1413,7 +1489,7 @@ public interface ExpressionList<T> {
|
||||
* .eq("status", Customer.Status.ACTIVE)
|
||||
* .gt("id", 0)
|
||||
* .endAnd()
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findList();
|
||||
* }</pre>
|
||||
*/
|
||||
@@ -1434,7 +1510,7 @@ public interface ExpressionList<T> {
|
||||
* .or()
|
||||
* .eq("status", Customer.Status.ACTIVE)
|
||||
* .isNull("anniversary")
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1454,7 +1530,7 @@ public interface ExpressionList<T> {
|
||||
* .eq("status", Customer.Status.ACTIVE)
|
||||
* .gt("id", 0)
|
||||
* .endAnd()
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1488,7 +1564,7 @@ public interface ExpressionList<T> {
|
||||
* .gt("id", 1)
|
||||
* .eq("anniversary", onAfter)
|
||||
* .endNot()
|
||||
* .orderBy()
|
||||
* .order()
|
||||
* .asc("name")
|
||||
* .findList();
|
||||
*
|
||||
+30
-8
@@ -1,8 +1,5 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
@@ -13,6 +10,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* The extended API for Database.
|
||||
@@ -69,7 +67,7 @@ public interface ExtendedServer {
|
||||
*
|
||||
* @return True if the query finds a matching row in the database
|
||||
*/
|
||||
<T> boolean exists(SpiQuery<?> ormQuery, SpiTransaction transaction);
|
||||
<T> boolean exists(Query<?> ormQuery, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Return the number of 'top level' or 'root' entities this query should return.
|
||||
@@ -94,11 +92,9 @@ public interface ExtendedServer {
|
||||
* {@link #findEachWhile(Query, Predicate, Transaction)} is preferred
|
||||
* to findIterate(). The reason is that those methods automatically take care of
|
||||
* closing the queryIterator (and the underlying jdbc statement and resultSet).
|
||||
* </p>
|
||||
* <p>
|
||||
* This is similar to findEach in that not all the result beans need to be held
|
||||
* in memory at the same time and as such is good for processing large queries.
|
||||
* </p>
|
||||
*
|
||||
* @see Query#findIterate()
|
||||
* @see Query#findEach(Consumer)
|
||||
@@ -107,6 +103,32 @@ public interface ExtendedServer {
|
||||
@Nonnull
|
||||
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query returning the result as a Stream.
|
||||
* <p>
|
||||
* Note that this can support very large queries iterating any number of results.
|
||||
* To do so internally it can use multiple persistence contexts.
|
||||
* <p>
|
||||
* Note that the stream needs to be closed so use with try with resources.
|
||||
* </p>
|
||||
*/
|
||||
@Nonnull
|
||||
<T> Stream<T> findStream(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to findStream().
|
||||
* <p>
|
||||
* Execute the query returning the result as a Stream.
|
||||
* <p>
|
||||
* Note that this can support very large queries iterating any number of results.
|
||||
* To do so internally it can use multiple persistence contexts.
|
||||
* <p>
|
||||
* Note that the stream needs to be closed so use with try with resources.
|
||||
*/
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
<T> Stream<T> findLargeStream(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query visiting the each bean one at a time.
|
||||
* <p>
|
||||
@@ -341,7 +363,7 @@ public interface ExtendedServer {
|
||||
* List<String> names =
|
||||
* DB.find(Customer.class)
|
||||
* .select("name")
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -353,7 +375,7 @@ public interface ExtendedServer {
|
||||
* .setDistinct(true)
|
||||
* .select("name")
|
||||
* .where().eq("status", Customer.Status.NEW)
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .setMaxRows(100)
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
+22
@@ -148,6 +148,8 @@ public class FetchConfig implements Serializable {
|
||||
|
||||
private boolean queryAll;
|
||||
|
||||
private boolean cache;
|
||||
|
||||
/**
|
||||
* Construct the fetch configuration object.
|
||||
*/
|
||||
@@ -188,6 +190,17 @@ public class FetchConfig implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eagerly fetch the beans fetching the beans from the L2 bean cache
|
||||
* and using the DB for beans not in the cache.
|
||||
*/
|
||||
public FetchConfig cache() {
|
||||
this.cache = true;
|
||||
this.queryBatchSize = 0;
|
||||
this.queryAll = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eagerly fetch the beans in this path as a separate query (rather than as
|
||||
* part of the main query).
|
||||
@@ -247,6 +260,13 @@ public class FetchConfig implements Serializable {
|
||||
return queryAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this uses L2 bean cache.
|
||||
*/
|
||||
public boolean isCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -255,6 +275,7 @@ public class FetchConfig implements Serializable {
|
||||
FetchConfig that = (FetchConfig) o;
|
||||
if (lazyBatchSize != that.lazyBatchSize) return false;
|
||||
if (queryBatchSize != that.queryBatchSize) return false;
|
||||
if (cache != that.cache) return false;
|
||||
return queryAll == that.queryAll;
|
||||
}
|
||||
|
||||
@@ -263,6 +284,7 @@ public class FetchConfig implements Serializable {
|
||||
int result = lazyBatchSize;
|
||||
result = 92821 * result + queryBatchSize;
|
||||
result = 92821 * result + (queryAll ? 1 : 0);
|
||||
result = 92821 * result + (cache ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+9
@@ -1,5 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.service.SpiFetchGroupQuery;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
@@ -111,4 +113,11 @@ public interface FetchGroup<T> {
|
||||
return XServiceProvider.fetchGroupOf(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a query to be used by query beans for constructing FetchGroup.
|
||||
*/
|
||||
static <T> SpiFetchGroupQuery<T> queryFor(Class<T> beanType) {
|
||||
return XServiceProvider.fetchGroupQueryFor(beanType);
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -67,12 +67,26 @@ public interface FetchGroupBuilder<T> {
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchQuery(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path including all its properties using L2 cache.
|
||||
* Cache misses fallback to fetchQuery().
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchCache(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path including specified properties using a query join.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchQuery(String path, String properties);
|
||||
|
||||
/**
|
||||
* Fetch the path including specified properties using L2 cache.
|
||||
* Cache misses fallback to fetchQuery().
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchCache(String path, String properties);
|
||||
|
||||
/**
|
||||
* Fetch the path including all its properties lazily.
|
||||
*/
|
||||
@@ -86,7 +86,7 @@ public interface Filter<T> {
|
||||
* expressions.
|
||||
* </p>
|
||||
* <p>
|
||||
* Refer to {@link Ebean#sort(List, String)} for more detail.
|
||||
* Refer to {@link DB#sort(List, String)} for more detail.
|
||||
* </p>
|
||||
*/
|
||||
Filter<T> sort(String sortByClause);
|
||||
@@ -32,17 +32,18 @@ import java.util.List;
|
||||
* public List<Customer> findNew() {
|
||||
* return query().where()
|
||||
* .eq("status", Customer.Status.NEW)
|
||||
* .orderBy("name")
|
||||
* .order("name")
|
||||
* .findList()
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Entity
|
||||
* @Entity
|
||||
* public class Customer extends BaseModel {
|
||||
*
|
||||
* public static final CustomerFinder find = new CustomerFinder();
|
||||
* ...
|
||||
*
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* When the Finder is registered as a field on Customer it can then be used like:
|
||||
@@ -79,12 +80,13 @@ public class Finder<I, T> {
|
||||
* // ... add extra customer specific finder methods
|
||||
* }
|
||||
*
|
||||
* @Entity
|
||||
* @Entity
|
||||
* public class Customer extends BaseModel {
|
||||
*
|
||||
* public static final CustomerFinder find = new CustomerFinder();
|
||||
* ...
|
||||
*
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
public Finder(Class<T> type) {
|
||||
@@ -32,19 +32,19 @@ import io.ebean.bean.EntityBean;
|
||||
* // Typically there is a common base model that has some
|
||||
* // common properties like the ones below
|
||||
*
|
||||
* @MappedSuperclass
|
||||
* public class BaseModel extends Model {
|
||||
* @MappedSuperclass
|
||||
* public class BaseModel extends Model {
|
||||
*
|
||||
* @Id Long id;
|
||||
* @Id Long id;
|
||||
*
|
||||
* @Version Long version;
|
||||
* @Version Long version;
|
||||
*
|
||||
* @WhenCreated Timestamp whenCreated;
|
||||
* @WhenCreated Timestamp whenCreated;
|
||||
*
|
||||
* @WhenUpdated Timestamp whenUpdated;
|
||||
*
|
||||
* ...
|
||||
* @WhenUpdated Timestamp whenUpdated;
|
||||
*
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* <h3>Extend the Model</h3>
|
||||
@@ -52,7 +52,7 @@ import io.ebean.bean.EntityBean;
|
||||
*
|
||||
* // Extend the mappedSuperclass
|
||||
*
|
||||
* @Entity @Table(name="o_account")
|
||||
* @Entity @Table(name="o_account")
|
||||
* public class Customer extends BaseModel {
|
||||
*
|
||||
* String name;
|
||||
@@ -75,6 +75,25 @@ import io.ebean.bean.EntityBean;
|
||||
*/
|
||||
public abstract class Model {
|
||||
|
||||
/**
|
||||
* The name of the database this entity will use, null for the default database.
|
||||
*/
|
||||
private final String _$dbName;
|
||||
|
||||
/**
|
||||
* Create using the default database.
|
||||
*/
|
||||
public Model() {
|
||||
this._$dbName = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create with a named database (typically not the default database).
|
||||
*/
|
||||
public Model(String dbName) {
|
||||
this._$dbName = dbName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying 'default' Database.
|
||||
* <p>
|
||||
@@ -107,17 +126,8 @@ public abstract class Model {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public static Database db() {
|
||||
return DB.getDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a named Database that is typically different to the default database.
|
||||
*
|
||||
* @param server The name of the Database. If this is null then the default Database is returned.
|
||||
*/
|
||||
public static Database db(String server) {
|
||||
return DB.byName(server);
|
||||
public Database db() {
|
||||
return DB.byName(_$dbName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,6 +192,13 @@ public abstract class Model {
|
||||
db().save(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save this entity with an explicit transaction.
|
||||
*/
|
||||
public void save(Transaction transaction) {
|
||||
db().save(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush any batched changes to the database.
|
||||
* <p>
|
||||
@@ -202,6 +219,13 @@ public abstract class Model {
|
||||
db().update(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this entity with an explicit transaction.
|
||||
*/
|
||||
public void update(Transaction transaction) {
|
||||
db().update(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert this entity.
|
||||
*
|
||||
@@ -211,6 +235,13 @@ public abstract class Model {
|
||||
db().insert(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert with an explicit transaction.
|
||||
*/
|
||||
public void insert(Transaction transaction) {
|
||||
db().insert(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this bean.
|
||||
* <p>
|
||||
@@ -232,6 +263,13 @@ public abstract class Model {
|
||||
return db().delete(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this entity with an explicit transaction.
|
||||
*/
|
||||
public boolean delete(Transaction transaction) {
|
||||
return db().delete(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a bean permanently without soft delete.
|
||||
* <p>
|
||||
@@ -246,24 +284,10 @@ public abstract class Model {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an update using this entity against the specified server.
|
||||
* Delete a bean permanently without soft delete using an explicit transaction.
|
||||
*/
|
||||
public void update(String server) {
|
||||
db(server).update(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an insert using this entity against the specified server.
|
||||
*/
|
||||
public void insert(String server) {
|
||||
db(server).insert(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a delete using this entity against the specified server.
|
||||
*/
|
||||
public boolean delete(String server) {
|
||||
return db(server).delete(this);
|
||||
public boolean deletePermanent(Transaction transaction) {
|
||||
return db().deletePermanent(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
+21
-10
@@ -1,7 +1,5 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.util.StringHelper;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -80,7 +78,6 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Add a property with ascending order to this OrderBy.
|
||||
*/
|
||||
public Query<T> asc(String propertyName, String collation) {
|
||||
|
||||
list.add(new Property(propertyName, true, collation));
|
||||
return query;
|
||||
}
|
||||
@@ -89,7 +86,6 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Add a property with descending order to this OrderBy.
|
||||
*/
|
||||
public Query<T> desc(String propertyName) {
|
||||
|
||||
list.add(new Property(propertyName, false));
|
||||
return query;
|
||||
}
|
||||
@@ -98,7 +94,6 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Add a property with descending order to this OrderBy.
|
||||
*/
|
||||
public Query<T> desc(String propertyName, String collation) {
|
||||
|
||||
list.add(new Property(propertyName, false, collation));
|
||||
return query;
|
||||
}
|
||||
@@ -108,7 +103,6 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Return true if the property is known to be contained in the order by clause.
|
||||
*/
|
||||
public boolean containsProperty(String propertyName) {
|
||||
|
||||
for (Property aList : list) {
|
||||
if (propertyName.equals(aList.getProperty())) {
|
||||
return true;
|
||||
@@ -161,10 +155,9 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Return a copy of the OrderBy.
|
||||
*/
|
||||
public OrderBy<T> copy() {
|
||||
|
||||
OrderBy<T> copy = new OrderBy<>();
|
||||
for (Property aList : list) {
|
||||
copy.add(aList.copy());
|
||||
for (Property property : list) {
|
||||
copy.add(property.copy());
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
@@ -241,6 +234,18 @@ public final class OrderBy<T> implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this order by can be used in select clause.
|
||||
*/
|
||||
public boolean supportsSelect() {
|
||||
for (Property property : list) {
|
||||
if (!property.supportsSelect()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A property and its ascending descending order.
|
||||
*/
|
||||
@@ -334,7 +339,7 @@ public final class OrderBy<T> implements Serializable {
|
||||
if (collation != null) {
|
||||
if (collation.contains("${}")) {
|
||||
// this is a complex collation, e.g. DB2 - we must replace the property
|
||||
sb.append(StringHelper.replaceString(collation, "${}", property));
|
||||
sb.append(collation.replace("${}", property));
|
||||
} else {
|
||||
sb.append(property);
|
||||
sb.append(" collate ").append(collation);
|
||||
@@ -401,6 +406,12 @@ public final class OrderBy<T> implements Serializable {
|
||||
this.ascending = ascending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support use in select clause if no collation or nulls ordering.
|
||||
*/
|
||||
boolean supportsSelect() {
|
||||
return nulls == null;
|
||||
}
|
||||
}
|
||||
|
||||
private void parse(String orderByClause) {
|
||||
+9
-2
@@ -60,6 +60,13 @@ import java.util.concurrent.Future;
|
||||
*/
|
||||
public interface PagedList<T> {
|
||||
|
||||
/**
|
||||
* Return an empty PagedList.
|
||||
*/
|
||||
static <B> PagedList<B> emptyList() {
|
||||
return new EmptyPagedList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the loading of the total row count in the background.
|
||||
* <pre>{@code
|
||||
@@ -87,8 +94,8 @@ public interface PagedList<T> {
|
||||
* Return the Future row count. You might get this if you wish to cancel the total row count query
|
||||
* or specify a timeout for the row count query.
|
||||
* <p>
|
||||
* The loadRowCount() & getTotalRowCount() methods internally make use of this getFutureRowCount() method.
|
||||
* Generally I expect people to prefer loadRowCount() & getTotalRowCount() over getFutureRowCount().
|
||||
* The loadRowCount() and getTotalRowCount() methods internally make use of this getFutureRowCount() method.
|
||||
* Generally I expect people to prefer loadRowCount() and getTotalRowCount() over getFutureRowCount().
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -18,7 +18,7 @@ import java.util.List;
|
||||
*
|
||||
* // where a bean is annotated with a complex
|
||||
* // natural key made of several properties
|
||||
* @Cache(naturalKey = {"store","code","sku"})
|
||||
* @Cache(naturalKey = {"store","code","sku"})
|
||||
*
|
||||
*
|
||||
* Pairs pairs = new Pairs("sku", "code");
|
||||
@@ -30,7 +30,7 @@ import java.util.List;
|
||||
* .where()
|
||||
* .eq("store", "def")
|
||||
* .inPairs(pairs) // IN clause with 'pairs' of values
|
||||
* .orderBy("sku desc")
|
||||
* .order("sku desc")
|
||||
*
|
||||
* // query expressions cover the natural key properties
|
||||
* // so we can choose to hit the L2 bean cache if we want
|
||||
+1
-1
@@ -6,7 +6,7 @@ package io.ebean;
|
||||
* Ebean has traditionally used Transaction scope for the PersistenceContext. This is used to change the scope to
|
||||
* use (by default) and explicitly set the scope to use for an individual query.
|
||||
*
|
||||
* @see io.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)
|
||||
* @see io.ebean.config.DatabaseConfig#setPersistenceContextScope(PersistenceContextScope)
|
||||
* @see Query#setPersistenceContextScope(PersistenceContextScope)
|
||||
*/
|
||||
public enum PersistenceContextScope {
|
||||
+18
-3
@@ -31,22 +31,37 @@ public interface ProfileLocation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the location description.
|
||||
* Obtain the description returning true if this is the initial call.
|
||||
*/
|
||||
String obtain();
|
||||
boolean obtain();
|
||||
|
||||
/**
|
||||
* Return a short version of the location description.
|
||||
*/
|
||||
String shortDescription();
|
||||
String location();
|
||||
|
||||
/**
|
||||
* Return the short label.
|
||||
*/
|
||||
String label();
|
||||
|
||||
/**
|
||||
* Return the full location.
|
||||
*/
|
||||
String fullLocation();
|
||||
|
||||
/**
|
||||
* Add execution time.
|
||||
*/
|
||||
void add(long executionTime);
|
||||
|
||||
/**
|
||||
* Return true if this request should be traced.
|
||||
*/
|
||||
boolean trace();
|
||||
|
||||
/**
|
||||
* Set the number of times to trace the transactions for this profile location.
|
||||
*/
|
||||
void setTraceCount(int traceCount);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package io.ebean;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -10,6 +11,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Object relational query for finding a List, Set, Map or single entity bean.
|
||||
@@ -23,7 +25,7 @@ import java.util.function.Predicate;
|
||||
* .where()
|
||||
* .like("customer.name","rob%")
|
||||
* .gt("orderDate",lastWeek)
|
||||
* .orderBy("customer.id, id desc")
|
||||
* .order("customer.id, id desc")
|
||||
* .setMaxRows(50)
|
||||
* .findList();
|
||||
*
|
||||
@@ -281,7 +283,7 @@ public interface Query<T> {
|
||||
/**
|
||||
* Specify the PersistenceContextScope to use for this query.
|
||||
* <p/>
|
||||
* When this is not set the 'default' configured on {@link io.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)}
|
||||
* When this is not set the 'default' configured on {@link io.ebean.config.DatabaseConfig#setPersistenceContextScope(PersistenceContextScope)}
|
||||
* is used - this value defaults to {@link PersistenceContextScope#TRANSACTION}.
|
||||
* <p/>
|
||||
* Note that the same persistence Context is used for subsequent lazy loading and query join queries.
|
||||
@@ -500,6 +502,14 @@ public interface Query<T> {
|
||||
*/
|
||||
Query<T> fetchQuery(String path, String fetchProperties);
|
||||
|
||||
/**
|
||||
* Fetch the path and properties using L2 bean cache.
|
||||
*
|
||||
* @param path The path of the beans we are fetching from L2 cache.
|
||||
* @param fetchProperties The properties that should be loaded.
|
||||
*/
|
||||
Query<T> fetchCache(String path, String fetchProperties);
|
||||
|
||||
/**
|
||||
* Fetch the path and properties lazily (via batch lazy loading).
|
||||
* <p>
|
||||
@@ -586,6 +596,11 @@ public interface Query<T> {
|
||||
*/
|
||||
Query<T> fetchQuery(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path eagerly using L2 cache.
|
||||
*/
|
||||
Query<T> fetchCache(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path lazily (via batch lazy loading).
|
||||
* <p>
|
||||
@@ -631,6 +646,21 @@ public interface Query<T> {
|
||||
*/
|
||||
Query<T> apply(FetchPath fetchPath);
|
||||
|
||||
/**
|
||||
* Execute the query using the given transaction.
|
||||
*/
|
||||
Query<T> usingTransaction(Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query using the given connection.
|
||||
*/
|
||||
Query<T> usingConnection(Connection connection);
|
||||
|
||||
/**
|
||||
* Execute the query using the given database.
|
||||
*/
|
||||
Query<T> usingDatabase(Database database);
|
||||
|
||||
/**
|
||||
* Execute the query returning the list of Id's.
|
||||
* <p>
|
||||
@@ -678,6 +708,52 @@ public interface Query<T> {
|
||||
@Nonnull
|
||||
QueryIterator<T> findIterate();
|
||||
|
||||
/**
|
||||
* Execute the query returning the result as a Stream.
|
||||
* <p>
|
||||
* Note that this can support very large queries iterating
|
||||
* any number of results. To do so internally it can use
|
||||
* multiple persistence contexts.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // use try with resources to ensure Stream is closed
|
||||
*
|
||||
* try (Stream<Customer> stream = query.findStream()) {
|
||||
* stream
|
||||
* .map(...)
|
||||
* .collect(...);
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
Stream<T> findStream();
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to findStream.
|
||||
* <p>
|
||||
* Execute the query returning the result as a Stream.
|
||||
* <p>
|
||||
* Note that this uses multiple persistence contexts such that we can use
|
||||
* it with a large number of results.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // use try with resources to ensure Stream is closed
|
||||
*
|
||||
* try (Stream<Customer> stream = query.findLargeStream()) {
|
||||
* stream
|
||||
* .map(...)
|
||||
* .collect(...);
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
Stream<T> findLargeStream();
|
||||
|
||||
/**
|
||||
* Execute the query processing the beans one at a time.
|
||||
* <p>
|
||||
@@ -817,7 +893,7 @@ public interface Query<T> {
|
||||
* List<String> names =
|
||||
* DB.find(Customer.class)
|
||||
* .select("name")
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -830,7 +906,7 @@ public interface Query<T> {
|
||||
* .setDistinct(true)
|
||||
* .select("name")
|
||||
* .where().eq("status", Customer.Status.NEW)
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .setMaxRows(100)
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
@@ -1115,6 +1191,30 @@ public interface Query<T> {
|
||||
*/
|
||||
Query<T> setParameter(int position, Object value);
|
||||
|
||||
/**
|
||||
* Bind the next positioned parameter.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* // a query with a positioned parameters
|
||||
* String oql = "where status = ? and name = ?";
|
||||
*
|
||||
* List<Order> list = DB.createQuery(Order.class, oql)
|
||||
* .setParameter(OrderStatus.NEW)
|
||||
* .setParameter("Rob")
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
Query<T> setParameter(Object value);
|
||||
|
||||
/**
|
||||
* Bind all the positioned parameters.
|
||||
* <p>
|
||||
* A convenience for multiple calls to {@link #setParameter(Object)}
|
||||
*/
|
||||
Query<T> setParameters(Object... values);
|
||||
|
||||
/**
|
||||
* Set the Id value to query. This is used with findOne().
|
||||
* <p>
|
||||
@@ -1261,10 +1361,6 @@ public interface Query<T> {
|
||||
* This follows SQL syntax using commas between each property with the
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #order(String)}.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> orderBy(String orderByClause);
|
||||
|
||||
@@ -1275,10 +1371,6 @@ public interface Query<T> {
|
||||
* This follows SQL syntax using commas between each property with the
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #orderBy(String)}.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> order(String orderByClause);
|
||||
|
||||
@@ -1288,10 +1380,8 @@ public interface Query<T> {
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #orderBy()}.
|
||||
* </p>
|
||||
* This is the same as <code>orderBy()</code>
|
||||
*/
|
||||
OrderBy<T> order();
|
||||
|
||||
@@ -1301,26 +1391,18 @@ public interface Query<T> {
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #order()}.
|
||||
* </p>
|
||||
* This is the same as <code>order()</code>
|
||||
*/
|
||||
OrderBy<T> orderBy();
|
||||
|
||||
/**
|
||||
* Set an OrderBy object to replace any existing OrderBy clause.
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #setOrderBy(OrderBy)}.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> setOrder(OrderBy<T> orderBy);
|
||||
|
||||
/**
|
||||
* Set an OrderBy object to replace any existing OrderBy clause.
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #setOrder(OrderBy)}.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> setOrderBy(OrderBy<T> orderBy);
|
||||
|
||||
@@ -1456,17 +1538,6 @@ public interface Query<T> {
|
||||
return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an id to identify this query for profiling purposes.
|
||||
* <p>
|
||||
* The profileId is expected to be unique for a given bean type.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that the profileId is treated as a short internally and has a MAX value of 32,767.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> setProfileId(int profileId);
|
||||
|
||||
/**
|
||||
* Set the profile location of this query. This is used to relate query execution metrics
|
||||
* back to a location like a specific line of code.
|
||||
+2
-2
@@ -23,9 +23,9 @@ import java.util.Iterator;
|
||||
* <h3>Try finally style</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* Query<Customer> query = server.find(Customer.class)
|
||||
* Query<Customer> query = database.find(Customer.class)
|
||||
* .where().gt("id", 0)
|
||||
* .orderBy("id")
|
||||
* .order("id")
|
||||
* .setMaxRows(2);
|
||||
*
|
||||
* QueryIterator<Customer> it = query.findIterate();
|
||||
@@ -6,17 +6,13 @@ package io.ebean;
|
||||
* <p>
|
||||
* If you don't want to build object graphs you can use {@link SqlQuery} instead
|
||||
* which returns {@link SqlRow} objects rather than entity beans.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>Unparsed RawSql:</b>
|
||||
* </p>
|
||||
* <p>
|
||||
* When RawSql is created via {@link RawSqlBuilder#unparsed(String)} then Ebean can not
|
||||
* modify the SQL at all. It can't add any extra expressions into the SQL.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>Parsed RawSql:</b>
|
||||
* </p>
|
||||
* <p>
|
||||
* When RawSql is created via {@link RawSqlBuilder#parse(String)} then Ebean will parse the
|
||||
* SQL and find places in the SQL where it can add extra where expressions, add
|
||||
@@ -24,16 +20,13 @@ package io.ebean;
|
||||
* explicitly tell Ebean where these insertion points are you can place special
|
||||
* strings into your SQL ({@code ${where}} or {@code ${andWhere}} and {@code ${having}} or
|
||||
* {@code ${andHaving})}.
|
||||
* </p>
|
||||
* <p>
|
||||
* If the SQL already includes a WHERE clause put in {@code ${andWhere}} in the location
|
||||
* you want Ebean to add any extra where expressions. If the SQL doesn't have a
|
||||
* WHERE clause put {@code ${where}} in instead. Similarly you can put in {@code ${having}} or
|
||||
* {@code ${andHaving}} where you want Ebean put add extra having expressions.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>Aggregates:</b>
|
||||
* </p>
|
||||
* <p>
|
||||
* Often RawSql will be used with Aggregate functions (sum, avg, max etc). The
|
||||
* follow example shows an example based on Total Order Amount -
|
||||
@@ -44,38 +37,37 @@ package io.ebean;
|
||||
* on RawSql and not based on a real DB Table or DB View. It has some properties
|
||||
* to hold the values for the aggregate functions (sum etc) and a @OneToOne
|
||||
* to Order.
|
||||
* </p>
|
||||
* <p>
|
||||
* <h3>Example OrderAggregate</h3>
|
||||
* <pre>{@code
|
||||
* ...
|
||||
* // @Sql indicates to that this bean
|
||||
* // is based on RawSql rather than a table
|
||||
* // @Sql indicates to that this bean
|
||||
* // is based on RawSql rather than a table
|
||||
*
|
||||
* @Entity
|
||||
* @Sql
|
||||
* public class OrderAggregate {
|
||||
* @Entity
|
||||
* @Sql
|
||||
* public class OrderAggregate {
|
||||
*
|
||||
* @OneToOne
|
||||
* Order order;
|
||||
* @OneToOne
|
||||
* Order order;
|
||||
*
|
||||
* Double totalAmount;
|
||||
* Double totalAmount;
|
||||
*
|
||||
* Double totalItems;
|
||||
*
|
||||
* // getters and setters
|
||||
* ...
|
||||
* Double totalItems;
|
||||
*
|
||||
* // getters and setters
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
*
|
||||
* <h3>Example 1:</h3>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = " select order_id, o.status, c.id, c.name, sum(d.order_qty*d.unit_price) as totalAmount"
|
||||
* + " from o_order o"
|
||||
* + " join o_customer c on c.id = o.kcustomer_id "
|
||||
* + " join o_order_detail d on d.order_id = o.id " + " group by order_id, o.status ";
|
||||
* String sql = " select order_id, o.status, c.id, c.name, sum(l.order_qty*l.unit_price) as totalAmount"
|
||||
* + " from order o"
|
||||
* + " join customer c on c.id = o.customer_id "
|
||||
* + " join order_line l on l.order_id = o.id " + " group by order_id, o.status ";
|
||||
*
|
||||
* RawSql rawSql = RawSqlBuilder.parse(sql)
|
||||
* // map the sql result columns to bean properties
|
||||
@@ -95,18 +87,17 @@ package io.ebean;
|
||||
*
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
*
|
||||
* <h3>Example 2:</h3>
|
||||
* <p>
|
||||
* The following example uses a FetchConfig().query() so that after the initial
|
||||
* RawSql query is executed Ebean executes a secondary query to fetch the
|
||||
* associated order status, orderDate along with the customer name.
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = " select order_id, 'ignoreMe', sum(d.order_qty*d.unit_price) as totalAmount "
|
||||
* + " from o_order_detail d"
|
||||
* String sql = " select order_id, 'ignoreMe', sum(l.order_qty*l.unit_price) as totalAmount "
|
||||
* + " from order_line l"
|
||||
* + " group by order_id ";
|
||||
*
|
||||
* RawSql rawSql = RawSqlBuilder.parse(sql)
|
||||
@@ -125,25 +116,23 @@ package io.ebean;
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
* <h3>Example 3: tableAliasMapping</h3>
|
||||
* <p>
|
||||
* Instead of mapping each column you can map each table alias to a path using tableAliasMapping().
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* String rs = "select o.id, o.status, c.id, c.name, "+
|
||||
* " d.id, d.order_qty, p.id, p.name " +
|
||||
* "from o_order o join o_customer c on c.id = o.kcustomer_id " +
|
||||
* "join o_order_detail d on d.order_id = o.id " +
|
||||
* "join o_product p on p.id = d.product_id " +
|
||||
* " l.id, l.order_qty, p.id, p.name " +
|
||||
* "from orders o join o_customer c on c.id = o.customer_id " +
|
||||
* "join order_line l on l.order_id = o.id " +
|
||||
* "join product p on p.id = l.product_id " +
|
||||
* "where o.id <= :maxOrderId and p.id = :productId "+
|
||||
* "order by o.id, d.id asc";
|
||||
* "order by o.id, l.id asc";
|
||||
*
|
||||
* RawSql rawSql = RawSqlBuilder.parse(rs)
|
||||
* .tableAliasMapping("c", "customer")
|
||||
* .tableAliasMapping("d", "details")
|
||||
* .tableAliasMapping("p", "details.product")
|
||||
* .tableAliasMapping("l", "lines")
|
||||
* .tableAliasMapping("p", "lines.product")
|
||||
* .create();
|
||||
*
|
||||
* List<Order> ordersFromRaw = DB.find(Order.class)
|
||||
@@ -154,9 +143,7 @@ package io.ebean;
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* Note that lazy loading also works with object graphs built with RawSql.
|
||||
* </p>
|
||||
*/
|
||||
public interface RawSql {
|
||||
|
||||
+4
-3
@@ -18,11 +18,11 @@ import java.sql.SQLException;
|
||||
* <pre>{@code
|
||||
*
|
||||
* //
|
||||
* // A mapper from ResultSet into our CustomerDto bean
|
||||
* // Map from ResultSet to CustomerDto bean
|
||||
* //
|
||||
* class CustomerMapper implements RowMapper<CustomerDto> {
|
||||
*
|
||||
* @Override
|
||||
* @Override
|
||||
* public CustomerDto map(ResultSet rset, int rowNum) throws SQLException {
|
||||
*
|
||||
* long id = rset.getLong(1);
|
||||
@@ -42,7 +42,8 @@ import java.sql.SQLException;
|
||||
*
|
||||
* CustomerDto rob = DB.sqlQuery(sql)
|
||||
* .setParameter(1, "Rob")
|
||||
* .findOne(CUSTOMER_MAPPER);
|
||||
* .mapTo(CUSTOMER_MAPPER)
|
||||
* .findOne();
|
||||
*
|
||||
*
|
||||
* }</pre>
|
||||
+9
@@ -50,4 +50,13 @@ public interface ScriptRunner {
|
||||
*/
|
||||
void run(URL resource, Map<String, String> placeholderMap);
|
||||
|
||||
/**
|
||||
* Run the raw provided DDL or SQL script.
|
||||
*
|
||||
* @param name The name of the script for logging purposes
|
||||
* @param content The SQL content
|
||||
* @param useAutoCommit Set to true to use auto commit true and continue when any errors occur
|
||||
*/
|
||||
void runScript(String name, String content, boolean useAutoCommit);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Thrown at SERIALIZABLE isolation level for non-recoverable concurrent conflict.
|
||||
*/
|
||||
public class SerializableConflictException extends OptimisticLockException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Create with a message and cause.
|
||||
*/
|
||||
public SerializableConflictException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
+168
-62
@@ -75,17 +75,15 @@ public interface SqlQuery extends Serializable {
|
||||
SqlRow findOne();
|
||||
|
||||
/**
|
||||
* Execute the query returning a single result using the mapper.
|
||||
*
|
||||
* @param mapper Used to map each ResultSet row into the result object.
|
||||
* Deprecated migrate to use {@link #mapTo(RowMapper)}
|
||||
*/
|
||||
@Deprecated
|
||||
<T> T findOne(RowMapper<T> mapper);
|
||||
|
||||
/**
|
||||
* Execute the query returning a list using the mapper.
|
||||
*
|
||||
* @param mapper Used to map each ResultSet row into the result object.
|
||||
* Deprecated migrate to use {@link #mapTo(RowMapper)}
|
||||
*/
|
||||
@Deprecated
|
||||
<T> List<T> findList(RowMapper<T> mapper);
|
||||
|
||||
/**
|
||||
@@ -125,77 +123,53 @@ public interface SqlQuery extends Serializable {
|
||||
Optional<SqlRow> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
* Execute the query returning a single scalar attribute.
|
||||
* <pre>@{code
|
||||
* Deprecated - migrate to <code>.mapToScalar(attributeType).findOne()</code>.
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "select max(unit_price) from o_order_detail where order_qty > ?";
|
||||
*
|
||||
* BigDecimal maxPrice = DB.sqlQuery(sql)
|
||||
* .setParameter(1, 2)
|
||||
* .findSingleAttribute(BigDecimal.class);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* The attributeType can be any scalar type that Ebean supports (includes javax time types, Joda types etc).
|
||||
* </p>
|
||||
*
|
||||
* @param attributeType The type of the returned value
|
||||
* .mapToScalar(BigDecimal.class)
|
||||
* .findOne();
|
||||
* }
|
||||
*/
|
||||
@Deprecated
|
||||
<T> T findSingleAttribute(Class<T> attributeType);
|
||||
|
||||
/**
|
||||
* Execute the query returning a single BigDecimal value.
|
||||
* <p>
|
||||
* This is an alias for <code>findSingleAttribute(BigDecimal.class)</code>
|
||||
* </p>
|
||||
* Deprecated - migrate to <code>.mapToScalar(BigDecimal.class).findOne()</code>.
|
||||
* <pre>{@code
|
||||
*
|
||||
* .mapToScalar(BigDecimal.class)
|
||||
* .findOne();
|
||||
* }
|
||||
*/
|
||||
@Deprecated
|
||||
BigDecimal findSingleDecimal();
|
||||
|
||||
/**
|
||||
* Execute the query returning a single Long value.
|
||||
* <p>
|
||||
* This is an alias for <code>findSingleAttribute(Long.class)</code>
|
||||
* </p>
|
||||
* Deprecated - migrate to <code>.mapToScalar(Long.class).findOne()</code>.
|
||||
* <pre>{@code
|
||||
*
|
||||
* .mapToScalar(Long.class)
|
||||
* .findOne();
|
||||
* }
|
||||
*/
|
||||
@Deprecated
|
||||
Long findSingleLong();
|
||||
|
||||
/**
|
||||
* Execute the query returning a list of scalar attribute values.
|
||||
*
|
||||
* Deprecated - migrate to <code>.mapToScalar(Long.class).findList()</code>.
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql =
|
||||
* " select (unit_price * order_qty) " +
|
||||
* " from o_order_detail " +
|
||||
* " where unit_price > ? " +
|
||||
* " order by (unit_price * order_qty) desc";
|
||||
*
|
||||
* //
|
||||
* List<BigDecimal> lineAmounts =
|
||||
* DB.sqlQuery(sql)
|
||||
* .setParameter(1, 3)
|
||||
* .findSingleAttributeList(BigDecimal.class);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* The attributeType can be any scalar type that Ebean supports (includes javax time types, Joda types etc).
|
||||
* </p>
|
||||
*
|
||||
* @param attributeType The type of the returned value
|
||||
* .mapToScalar(Long.class)
|
||||
* .findList();
|
||||
* }
|
||||
*/
|
||||
@Deprecated
|
||||
<T> List<T> findSingleAttributeList(Class<T> attributeType);
|
||||
|
||||
/**
|
||||
* The same as bind for named parameters.
|
||||
*/
|
||||
SqlQuery setParameter(String name, Object value);
|
||||
|
||||
/**
|
||||
* Set one of more positioned parameters.
|
||||
* <p>
|
||||
* This is a convenient alternative to multiple calls setParameter().
|
||||
* This is a convenient alternative to multiple calls to {@link #setParameter(Object)}.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -203,27 +177,104 @@ public interface SqlQuery extends Serializable {
|
||||
*
|
||||
* List<SqlRow> list =
|
||||
* DB.sqlQuery(sql)
|
||||
* .setParams("Rob", Status.NEW)
|
||||
* .setParameters("Rob", Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
*
|
||||
* // is the same as ...
|
||||
* // effectively the same as ...
|
||||
*
|
||||
* .setParameter("Rob")
|
||||
* .setParameter("Status.NEW)
|
||||
*
|
||||
* // and ...
|
||||
*
|
||||
* List<SqlRow> list =
|
||||
* DB.sqlQuery(sql)
|
||||
* .setParameter(1, "Rob")
|
||||
* .setParameter(2, "Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
SqlQuery setParameters(Object... values);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to setParameters(Object... values)
|
||||
*/
|
||||
@Deprecated
|
||||
SqlQuery setParams(Object... values);
|
||||
|
||||
/**
|
||||
* The same as bind for positioned parameters.
|
||||
* Set the next bind parameter by position.
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "select id, name from customer where name like ? and status = ?";
|
||||
*
|
||||
* List<SqlRow> list =
|
||||
* DB.sqlQuery(sql)
|
||||
* .setParameter("Rob")
|
||||
* .setParameter("Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
* // the same as ...
|
||||
*
|
||||
* .setParameters("Rob", Status.NEW)
|
||||
*
|
||||
* // and ...
|
||||
*
|
||||
* .setParameter(1, "Rob")
|
||||
* .setParameter(2, "Status.NEW)
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* When binding a collection of values into a IN expression we should use
|
||||
* indexed parameters like ?1, ?2, ?3 etc rather than just ?.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "select c.id, c.name from customer c where c.name in (?1)";
|
||||
*
|
||||
* List<SqlRow> rows = DB.sqlQuery(sql)
|
||||
* .setParameter(asList("Rob", "Fiona", "Jack"))
|
||||
* .findList();
|
||||
*
|
||||
*
|
||||
* List<SqlRow> rows = DB.sqlQuery(sql)
|
||||
* .setParameter(1, asList("Rob", "Fiona", "Jack"))
|
||||
* .findList();
|
||||
* }</pre>
|
||||
*
|
||||
* @param value The value to bind
|
||||
*/
|
||||
SqlQuery setParameter(Object value);
|
||||
|
||||
/**
|
||||
* Bind the parameter by its index position (1 based like JDBC).
|
||||
* <p>
|
||||
* When binding a collection of values into a IN expression we should use
|
||||
* indexed parameters like ?1, ?2, ?3 etc rather than just ?.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "select c.id, c.name from customer c where c.name in (?1)";
|
||||
*
|
||||
* List<SqlRow> rows = DB.sqlQuery(sql)
|
||||
* .setParameter(asList("Rob", "Fiona", "Jack"))
|
||||
* .findList();
|
||||
*
|
||||
*
|
||||
* List<SqlRow> rows = DB.sqlQuery(sql)
|
||||
* .setParameter(1, asList("Rob", "Fiona", "Jack"))
|
||||
* .findList();
|
||||
* }</pre>
|
||||
*/
|
||||
SqlQuery setParameter(int position, Object value);
|
||||
|
||||
/**
|
||||
* Bind the named parameter value.
|
||||
*/
|
||||
SqlQuery setParameter(String name, Object value);
|
||||
|
||||
/**
|
||||
* Set the index of the first row of the results to return.
|
||||
*/
|
||||
@@ -260,4 +311,59 @@ public interface SqlQuery extends Serializable {
|
||||
*/
|
||||
SqlQuery setBufferFetchSizeHint(int bufferFetchSizeHint);
|
||||
|
||||
/**
|
||||
* The query result maps to a single scalar value like Long, BigDecimal,
|
||||
* String, UUID, OffsetDateTime etc.
|
||||
* <p>
|
||||
* Any scalar type Ebean is aware of can be used including java time
|
||||
* types like Instant, LocalDate, OffsetDateTime, UUID, Inet, Cdir etc.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = " select min(updtime) from o_order_detail " +
|
||||
* " where unit_price > ? and updtime is not null ";
|
||||
*
|
||||
* OffsetDateTime minCreated = DB.sqlQuery(sql)
|
||||
* .setParameter(42)
|
||||
* .mapToScalar(OffsetDateTime.class)
|
||||
* .findOne();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param attributeType The type the result is returned as
|
||||
* @return The query to execute via findOne() findList() etc
|
||||
*/
|
||||
<T> TypeQuery<T> mapToScalar(Class<T> attributeType);
|
||||
|
||||
/**
|
||||
* Use a RowMapper to map the result to beans.
|
||||
*
|
||||
* @param mapper Maps rows to beans
|
||||
* @param <T> The type of beans mapped to
|
||||
* @return The query to execute by findOne() findList() etc
|
||||
*/
|
||||
<T> TypeQuery<T> mapTo(RowMapper<T> mapper);
|
||||
|
||||
/**
|
||||
* Query mapping to single scalar values.
|
||||
*
|
||||
* @param <T> The type of the scalar values
|
||||
*/
|
||||
interface TypeQuery<T> {
|
||||
|
||||
/**
|
||||
* Return the single value.
|
||||
*/
|
||||
T findOne();
|
||||
|
||||
/**
|
||||
* Return the single value that is optional.
|
||||
*/
|
||||
Optional<T> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
* Return the list of values.
|
||||
*/
|
||||
List<T> findList();
|
||||
}
|
||||
}
|
||||
+66
-27
@@ -5,18 +5,16 @@ package io.ebean;
|
||||
* <p>
|
||||
* Provides a simple way to execute raw SQL insert update or delete statements
|
||||
* without having to resort to JDBC.
|
||||
* </p>
|
||||
* <p>
|
||||
* Supports the use of positioned or named parameters and can automatically
|
||||
* notify Ebean of the table modified so that Ebean can maintain its cache.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that {@link #setAutoTableMod(boolean)} and
|
||||
* Ebean#externalModification(String, boolean, boolean, boolean)} can be to
|
||||
* notify Ebean of external changes and enable Ebean to maintain it's "L2"
|
||||
* server cache.
|
||||
* </p>
|
||||
*
|
||||
* <h2>Positioned parameter example</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // example using 'positioned' parameters
|
||||
@@ -30,6 +28,7 @@ package io.ebean;
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h2>Named parameter example</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // example using 'named' parameters
|
||||
@@ -45,8 +44,31 @@ package io.ebean;
|
||||
* String msg = "There were " + rows + " rows updated";
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h2>Index parameter examples (e.g. ?1, ?2, ?3 ...)</h2>
|
||||
* <p>
|
||||
* <h3>Example: Using setNextParameter()</h3>
|
||||
* We can use index parameters like ?1, ?2, ?3 etc when binding arrays/collections
|
||||
* of values into an IN expression.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // Binding a list of 3 values (9991, 9992, 9993) into an IN expression
|
||||
*
|
||||
* DB.sqlUpdate("delete from o_customer where name = ? and id in (?2)")
|
||||
* .setParameter(1, "Foo")
|
||||
* .setParameter(2, asList(9991, 9992, 9993))
|
||||
* .execute();
|
||||
*
|
||||
* // note this effectively is the same as
|
||||
*
|
||||
* DB.sqlUpdate("delete from o_customer where name = ? and id in (?2)")
|
||||
* .setParameter("Foo")
|
||||
* .setParameter(asList(9991, 9992, 9993))
|
||||
* .execute();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Example: Using setParameter()</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "insert into audit_log (id, description, modified_description) values (?,?,?)";
|
||||
@@ -56,19 +78,19 @@ package io.ebean;
|
||||
* try (Transaction txn = DB.beginTransaction()) {
|
||||
* txn.setBatchMode(true);
|
||||
*
|
||||
* insert.setNextParameter(10000);
|
||||
* insert.setNextParameter("hello");
|
||||
* insert.setNextParameter("rob");
|
||||
* insert.setParameter(10000);
|
||||
* insert.setParameter("hello");
|
||||
* insert.setParameter("rob");
|
||||
* insert.execute();
|
||||
*
|
||||
* insert.setNextParameter(10001);
|
||||
* insert.setNextParameter("goodbye");
|
||||
* insert.setNextParameter("rob");
|
||||
* insert.setParameter(10001);
|
||||
* insert.setParameter("goodbye");
|
||||
* insert.setParameter("rob");
|
||||
* insert.execute();
|
||||
*
|
||||
* insert.setNextParameter(10002);
|
||||
* insert.setNextParameter("chow");
|
||||
* insert.setNextParameter("bob");
|
||||
* insert.setParameter(10002);
|
||||
* insert.setParameter("chow");
|
||||
* insert.setParameter("bob");
|
||||
* insert.execute();
|
||||
*
|
||||
* txn.commit();
|
||||
@@ -81,19 +103,19 @@ package io.ebean;
|
||||
*
|
||||
* try (Transaction txn = DB.beginTransaction()) {
|
||||
*
|
||||
* insert.setNextParameter(10000);
|
||||
* insert.setNextParameter("hello");
|
||||
* insert.setNextParameter("rob");
|
||||
* insert.setParameter(10000);
|
||||
* insert.setParameter("hello");
|
||||
* insert.setParameter("rob");
|
||||
* insert.addBatch();
|
||||
*
|
||||
* insert.setNextParameter(10001);
|
||||
* insert.setNextParameter("goodbye");
|
||||
* insert.setNextParameter("rob");
|
||||
* insert.setParameter(10001);
|
||||
* insert.setParameter("goodbye");
|
||||
* insert.setParameter("rob");
|
||||
* insert.addBatch();
|
||||
*
|
||||
* insert.setNextParameter(10002);
|
||||
* insert.setNextParameter("chow");
|
||||
* insert.setNextParameter("bob");
|
||||
* insert.setParameter(10002);
|
||||
* insert.setParameter("chow");
|
||||
* insert.setParameter("bob");
|
||||
* insert.addBatch();
|
||||
*
|
||||
* int[] rows = insert.executeBatch();
|
||||
@@ -126,8 +148,6 @@ public interface SqlUpdate {
|
||||
* {@link Transaction#setBatchMode(boolean)} and
|
||||
* {@link Transaction#setBatchSize(int)}.
|
||||
* </p>
|
||||
*
|
||||
* @see Ebean#execute(SqlUpdate)
|
||||
*/
|
||||
int execute();
|
||||
|
||||
@@ -241,28 +261,47 @@ public interface SqlUpdate {
|
||||
* String sql = "insert into audit_log (id, name, version) values (?,?,?)";
|
||||
*
|
||||
* DB.sqlUpdate(sql)
|
||||
* .setParams(UUID.randomUUID(), "Hello", 1)
|
||||
* .setParameters(UUID.randomUUID(), "Hello", 1)
|
||||
* .executeNow();
|
||||
*
|
||||
*
|
||||
* // is the same as ...
|
||||
*
|
||||
* DB.sqlUpdate(sql)
|
||||
* .setParameter(UUID.randomUUID())
|
||||
* .setParameter("Hello")
|
||||
* .setParameter(1)
|
||||
* .executeNow();
|
||||
*
|
||||
* // which is the same as ...
|
||||
*
|
||||
* DB.sqlUpdate(sql)
|
||||
* .setParameter(1, UUID.randomUUID())
|
||||
* .setParameter(2, "Hello")
|
||||
* .setParameter(3, 1)
|
||||
* .executeNow();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
*/
|
||||
SqlUpdate setParameters(Object... values);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to setParameters(Object... values).
|
||||
*/
|
||||
@Deprecated
|
||||
SqlUpdate setParams(Object... values);
|
||||
|
||||
/**
|
||||
* Set the next positioned parameter.
|
||||
* Set the next bind parameter by position.
|
||||
*
|
||||
* @param value The value to bind
|
||||
*/
|
||||
SqlUpdate setParameter(Object value);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to setParameter(value).
|
||||
*/
|
||||
@Deprecated
|
||||
SqlUpdate setNextParameter(Object value);
|
||||
|
||||
/**
|
||||
+46
-14
@@ -3,7 +3,7 @@ package io.ebean;
|
||||
import io.ebean.annotation.DocStoreMode;
|
||||
import io.ebean.annotation.PersistBatch;
|
||||
import io.ebean.config.DocStoreConfig;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.Connection;
|
||||
@@ -27,7 +27,7 @@ public interface Transaction extends AutoCloseable {
|
||||
* @see Database#currentTransaction()
|
||||
*/
|
||||
static Transaction current() {
|
||||
return Ebean.currentTransaction();
|
||||
return DB.currentTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,7 +226,7 @@ public interface Transaction extends AutoCloseable {
|
||||
/**
|
||||
* Set if the L2 cache should be skipped for "find by id" and "find by natural key" queries.
|
||||
* <p>
|
||||
* By default {@link ServerConfig#isSkipCacheAfterWrite()} is true and that means that for
|
||||
* By default {@link DatabaseConfig#isSkipCacheAfterWrite()} is true and that means that for
|
||||
* "find by id" and "find by natural key" queries which normally hit L2 bean cache automatically
|
||||
* - will not do so after a persist/write on the transaction.
|
||||
* </p>
|
||||
@@ -235,7 +235,7 @@ public interface Transaction extends AutoCloseable {
|
||||
* will skip the L2 bean cache or not (regardless of whether the transaction is considered "read only").
|
||||
* </p>
|
||||
* <p>
|
||||
* Refer to {@link ServerConfig#setSkipCacheAfterWrite(boolean)} for configuring the default behavior
|
||||
* Refer to {@link DatabaseConfig#setSkipCacheAfterWrite(boolean)} for configuring the default behavior
|
||||
* for using the L2 bean cache in transactions spanning multiple query/persist requests.
|
||||
* </p>
|
||||
*
|
||||
@@ -276,7 +276,7 @@ public interface Transaction extends AutoCloseable {
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see ServerConfig#isSkipCacheAfterWrite()
|
||||
* @see DatabaseConfig#isSkipCacheAfterWrite()
|
||||
*/
|
||||
void setSkipCache(boolean skipCache);
|
||||
|
||||
@@ -295,7 +295,7 @@ public interface Transaction extends AutoCloseable {
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* try (Transaction transaction = server.beginTransaction()) {
|
||||
* try (Transaction transaction = database.beginTransaction()) {
|
||||
*
|
||||
* // turn on JDBC batch
|
||||
* transaction.setBatchMode(true);
|
||||
@@ -313,12 +313,12 @@ public interface Transaction extends AutoCloseable {
|
||||
* <h3>getGeneratedKeys</h3>
|
||||
* <p>
|
||||
* Often with large batch inserts we want to turn off getGeneratedKeys. We do
|
||||
* this via {@link #setBatchGetGeneratedKeys(boolean)}.
|
||||
* this via {@link #setGetGeneratedKeys(boolean)}.
|
||||
* Also note that some JDBC drivers do not support getGeneratedKeys in JDBC batch mode.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* try (Transaction transaction = server.beginTransaction()) {
|
||||
* try (Transaction transaction = database.beginTransaction()) {
|
||||
*
|
||||
* transaction.setBatchMode(true);
|
||||
* transaction.setBatchSize(100);
|
||||
@@ -342,7 +342,7 @@ public interface Transaction extends AutoCloseable {
|
||||
* </p>
|
||||
* <p>
|
||||
* We use {@link #flush()} to explicitly flush the batch and we can use
|
||||
* {@link #setBatchFlushOnQuery(boolean)} and {@link #setBatchFlushOnMixed(boolean)}
|
||||
* {@link #setFlushOnQuery(boolean)} and {@link #setFlushOnMixed(boolean)}
|
||||
* to control the automatic flushing behaviour.
|
||||
* </p>
|
||||
* <p>
|
||||
@@ -402,7 +402,7 @@ public interface Transaction extends AutoCloseable {
|
||||
* </p>
|
||||
*
|
||||
* @param batchMode the batch mode to use per save(), insert(), update() or delete()
|
||||
* @see io.ebean.config.ServerConfig#setPersistBatchOnCascade(PersistBatch)
|
||||
* @see io.ebean.config.DatabaseConfig#setPersistBatchOnCascade(PersistBatch)
|
||||
*/
|
||||
void setBatchOnCascade(boolean batchMode);
|
||||
|
||||
@@ -432,7 +432,15 @@ public interface Transaction extends AutoCloseable {
|
||||
* number of objects and you don't care about getting back the ids.
|
||||
* </p>
|
||||
*/
|
||||
void setBatchGetGeneratedKeys(boolean getGeneratedKeys);
|
||||
void setGetGeneratedKeys(boolean getGeneratedKeys);
|
||||
|
||||
/**
|
||||
* Deprecated renamed to setGetGeneratedKeys().
|
||||
*/
|
||||
@Deprecated
|
||||
default void setBatchGetGeneratedKeys(boolean getGeneratedKeys) {
|
||||
setGetGeneratedKeys(getGeneratedKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* By default when mixing UpdateSql (or CallableSql) with Beans the batch is
|
||||
@@ -449,7 +457,15 @@ public interface Transaction extends AutoCloseable {
|
||||
* have a 2 step process (delayed binding).
|
||||
* </p>
|
||||
*/
|
||||
void setBatchFlushOnMixed(boolean batchFlushOnMixed);
|
||||
void setFlushOnMixed(boolean batchFlushOnMixed);
|
||||
|
||||
/**
|
||||
* Deprecated renamed to setFlushOnMixed().
|
||||
*/
|
||||
@Deprecated
|
||||
default void setBatchFlushOnMixed(boolean batchFlushOnMixed) {
|
||||
setFlushOnMixed(batchFlushOnMixed);
|
||||
}
|
||||
|
||||
/**
|
||||
* By default executing a query will automatically flush any batched
|
||||
@@ -459,7 +475,15 @@ public interface Transaction extends AutoCloseable {
|
||||
* execute a query and the batch will not be automatically flushed.
|
||||
* </p>
|
||||
*/
|
||||
void setBatchFlushOnQuery(boolean batchFlushOnQuery);
|
||||
void setFlushOnQuery(boolean batchFlushOnQuery);
|
||||
|
||||
/**
|
||||
* Deprecated renamed to setFlushOnQuery().
|
||||
*/
|
||||
@Deprecated
|
||||
default void setBatchFlushOnQuery(boolean batchFlushOnQuery) {
|
||||
setFlushOnQuery(batchFlushOnQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the batch (of persisted beans or executed UpdateSql etc)
|
||||
@@ -468,7 +492,15 @@ public interface Transaction extends AutoCloseable {
|
||||
* The default is for this to be true.
|
||||
* </p>
|
||||
*/
|
||||
boolean isBatchFlushOnQuery();
|
||||
boolean isFlushOnQuery();
|
||||
|
||||
/**
|
||||
* Deprecated renamed to isFlushOnQuery().
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean isBatchFlushOnQuery() {
|
||||
return isFlushOnQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* The batch will be flushing automatically but you can use this to explicitly
|
||||
@@ -12,16 +12,16 @@ import java.util.concurrent.Callable;
|
||||
* <p>
|
||||
* This information matches the features of the Transactional annotation. You
|
||||
* can use it directly with Runnable or Callable via
|
||||
* {@link Ebean#execute(TxScope, Runnable)} or
|
||||
* {@link Ebean#executeCall(TxScope, Callable)}.
|
||||
* {@link DB#execute(TxScope, Runnable)} or
|
||||
* {@link DB#executeCall(TxScope, Callable)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* This object is used internally with the enhancement of a method with
|
||||
* Transactional annotation.
|
||||
* </p>
|
||||
*
|
||||
* @see Ebean#execute(TxScope, Runnable)
|
||||
* @see Ebean#executeCall(TxScope, Callable)
|
||||
* @see DB#execute(TxScope, Runnable)
|
||||
* @see DB#executeCall(TxScope, Callable)
|
||||
*/
|
||||
public final class TxScope {
|
||||
|
||||
@@ -12,26 +12,27 @@ package io.ebean;
|
||||
* The following is an example of named updates on an entity bean.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
* ...
|
||||
* @NamedUpdates(value = {
|
||||
* @NamedUpdate(
|
||||
* name = "setTitle",
|
||||
* notifyCache = false,
|
||||
* update = "update topic set title = :title, postCount = :count where id = :id"),
|
||||
* @NamedUpdate(
|
||||
* name = "setPostCount",
|
||||
* notifyCache = false,
|
||||
* update = "update f_topic set post_count = :postCount where id = :id"),
|
||||
* @NamedUpdate(
|
||||
* name = "incrementPostCount",
|
||||
* notifyCache = false,
|
||||
* update = "update Topic set postCount = postCount + 1 where id = :id")
|
||||
* //update = "update f_topic set post_count = post_count + 1 where id = :id")
|
||||
* })
|
||||
* @Entity
|
||||
* @Table(name = "f_topic")
|
||||
* public class Topic {
|
||||
* ...
|
||||
* ...
|
||||
* @NamedUpdates(value = {
|
||||
* @NamedUpdate(
|
||||
* name = "setTitle",
|
||||
* notifyCache = false,
|
||||
* update = "update topic set title = :title, postCount = :count where id = :id"),
|
||||
* @NamedUpdate(
|
||||
* name = "setPostCount",
|
||||
* notifyCache = false,
|
||||
* update = "update f_topic set post_count = :postCount where id = :id"),
|
||||
* @NamedUpdate(
|
||||
* name = "incrementPostCount",
|
||||
* notifyCache = false,
|
||||
* update = "update Topic set postCount = postCount + 1 where id = :id")
|
||||
* //update = "update f_topic set post_count = post_count + 1 where id = :id")
|
||||
* })
|
||||
* @Entity
|
||||
* @Table(name = "f_topic")
|
||||
* public class Topic {
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
+15
-13
@@ -1,5 +1,6 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.service.SpiFetchGroupQuery;
|
||||
import io.ebean.service.SpiFetchGroupService;
|
||||
import io.ebean.service.SpiProfileLocationFactory;
|
||||
import io.ebean.service.SpiRawSqlService;
|
||||
@@ -19,29 +20,23 @@ class XServiceProvider {
|
||||
private static SpiFetchGroupService fetchGroupService = initSpiFetchGroupService();
|
||||
|
||||
private static SpiFetchGroupService initSpiFetchGroupService() {
|
||||
Iterator<SpiFetchGroupService> loader = ServiceLoader.load(SpiFetchGroupService.class).iterator();
|
||||
if (loader.hasNext()) {
|
||||
return loader.next();
|
||||
}
|
||||
throw new IllegalStateException("No service implementation found for SpiFetchGroupService?");
|
||||
return loadFirstService(SpiFetchGroupService.class);
|
||||
}
|
||||
|
||||
private static SpiRawSqlService initRawSql() {
|
||||
|
||||
Iterator<SpiRawSqlService> loader = ServiceLoader.load(SpiRawSqlService.class).iterator();
|
||||
if (loader.hasNext()) {
|
||||
return loader.next();
|
||||
}
|
||||
throw new IllegalStateException("No service implementation found for SpiRawSqlService?");
|
||||
return loadFirstService(SpiRawSqlService.class);
|
||||
}
|
||||
|
||||
private static SpiProfileLocationFactory initProfileLocation() {
|
||||
return loadFirstService(SpiProfileLocationFactory.class);
|
||||
}
|
||||
|
||||
Iterator<SpiProfileLocationFactory> loader = ServiceLoader.load(SpiProfileLocationFactory.class).iterator();
|
||||
private static <T> T loadFirstService(Class<T> cls) {
|
||||
Iterator<T> loader = ServiceLoader.load(cls).iterator();
|
||||
if (loader.hasNext()) {
|
||||
return loader.next();
|
||||
}
|
||||
throw new IllegalStateException("No service implementation found for SpiProfileLocationFactory?");
|
||||
throw new IllegalStateException("No service implementation found for " + cls);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,4 +66,11 @@ class XServiceProvider {
|
||||
static <T> FetchGroupBuilder<T> fetchGroupOf(Class<T> cls) {
|
||||
return fetchGroupService.of(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FetchGroup Query for building fetch groups via query beans.
|
||||
*/
|
||||
static <T> SpiFetchGroupQuery<T> fetchGroupQueryFor(Class<T> cls) {
|
||||
return fetchGroupService.queryFor(cls);
|
||||
}
|
||||
}
|
||||
+7
@@ -1,5 +1,7 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
/**
|
||||
* Loads a entity bean.
|
||||
* <p>
|
||||
@@ -18,4 +20,9 @@ public interface BeanLoader {
|
||||
*/
|
||||
void loadBean(EntityBeanIntercept ebi);
|
||||
|
||||
/**
|
||||
* Obtain a lock on the loader.
|
||||
*/
|
||||
Lock lock();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
/**
|
||||
* A call origin for query execution profiling to collect graph use (for query tuning).
|
||||
*/
|
||||
public interface CallOrigin {
|
||||
|
||||
/**
|
||||
* Return the top element. Typically the top stack element with class and line.
|
||||
*/
|
||||
String getTopElement();
|
||||
|
||||
/**
|
||||
* Return the full description of the call origin.
|
||||
*/
|
||||
String getFullDescription();
|
||||
|
||||
/**
|
||||
* Compute and return an origin key based on the query hash.
|
||||
*/
|
||||
String getOriginKey(int queryHash);
|
||||
}
|
||||
+22
-59
@@ -3,6 +3,8 @@ package io.ebean.bean;
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.ebean.util.EncodeB64.enc;
|
||||
|
||||
/**
|
||||
* Represent the call stack (stack trace elements).
|
||||
* <p>
|
||||
@@ -17,15 +19,15 @@ import java.util.Arrays;
|
||||
* Note the call stack is trimmed to remove the common ebean internal elements.
|
||||
* </p>
|
||||
*/
|
||||
public final class CallStack implements Serializable {
|
||||
public final class CallStack implements Serializable, CallOrigin {
|
||||
|
||||
private static final long serialVersionUID = -8590644046907438579L;
|
||||
|
||||
private static final String NEWLINE = "\n";
|
||||
|
||||
private final String zeroHash;
|
||||
private final String pathHash;
|
||||
|
||||
private final StackTraceElement[] callStack;
|
||||
|
||||
private final int hc;
|
||||
|
||||
public CallStack(StackTraceElement[] callStack, int zeroHash, int pathHash) {
|
||||
@@ -37,12 +39,17 @@ public final class CallStack implements Serializable {
|
||||
|
||||
private int computeHashCode() {
|
||||
int hc = 0;
|
||||
for (StackTraceElement aCallStack : callStack) {
|
||||
hc = 92821 * hc + aCallStack.hashCode();
|
||||
for (StackTraceElement element : callStack) {
|
||||
hc = 92821 * hc + element.hashCode();
|
||||
}
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return zeroHash + ":" + pathHash + ":" + callStack[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hc;
|
||||
@@ -63,73 +70,29 @@ public final class CallStack implements Serializable {
|
||||
/**
|
||||
* Return the first element of the call stack.
|
||||
*/
|
||||
public StackTraceElement getFirstStackTraceElement() {
|
||||
return callStack[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the call stack.
|
||||
*/
|
||||
public StackTraceElement[] getCallStack() {
|
||||
return callStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hash for the first stack element.
|
||||
*/
|
||||
public String getZeroHash() {
|
||||
return zeroHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hash for the stack elements (excluding first stack element).
|
||||
*/
|
||||
public String getPathHash() {
|
||||
return pathHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return zeroHash + ":" + pathHash + ":" + callStack[0];
|
||||
public String getTopElement() {
|
||||
return callStack[0].toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the call stack lines appended with the given newLine string.
|
||||
*/
|
||||
public String description(String newLine) {
|
||||
@Override
|
||||
public String getFullDescription() {
|
||||
StringBuilder sb = new StringBuilder(400);
|
||||
for (StackTraceElement aCallStack : callStack) {
|
||||
sb.append(aCallStack.toString()).append(newLine);
|
||||
for (int i = 0; i < callStack.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(NEWLINE);
|
||||
}
|
||||
sb.append(callStack[i].toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginKey(int queryHash) {
|
||||
return enc(queryHash) + "." + zeroHash + "." + pathHash;
|
||||
}
|
||||
|
||||
private static final int radix = 1 << 6;
|
||||
private static final int mask = radix - 1;
|
||||
|
||||
/**
|
||||
* Convert the integer to unsigned base 64.
|
||||
*/
|
||||
public static String enc(int i) {
|
||||
char[] buf = new char[32];
|
||||
int charPos = 32;
|
||||
do {
|
||||
buf[--charPos] = intToBase64[i & mask];
|
||||
i >>>= 6;
|
||||
} while (i != 0);
|
||||
|
||||
return new String(buf, charPos, (32 - charPos));
|
||||
}
|
||||
|
||||
private static final char intToBase64[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
|
||||
};
|
||||
}
|
||||
+36
-12
@@ -16,12 +16,16 @@ public interface EntityBean extends Serializable {
|
||||
/**
|
||||
* Return all the property names in defined order.
|
||||
*/
|
||||
String[] _ebean_getPropertyNames();
|
||||
default String[] _ebean_getPropertyNames() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property name at the given position.
|
||||
*/
|
||||
String _ebean_getPropertyName(int pos);
|
||||
default String _ebean_getPropertyName(int pos) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the enhancement marker value.
|
||||
@@ -30,28 +34,38 @@ public interface EntityBean extends Serializable {
|
||||
* entity classes are enhanced (specifically not just a super class).
|
||||
* </p>
|
||||
*/
|
||||
String _ebean_getMarker();
|
||||
default String _ebean_getMarker() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new entity bean instance.
|
||||
*/
|
||||
Object _ebean_newInstance();
|
||||
default Object _ebean_newInstance() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated method that sets the loaded state on all the embedded beans on
|
||||
* this entity bean by using EntityBeanIntercept.setEmbeddedLoaded(Object o);
|
||||
*/
|
||||
void _ebean_setEmbeddedLoaded();
|
||||
default void _ebean_setEmbeddedLoaded() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if any embedded beans are new or dirty.
|
||||
*/
|
||||
boolean _ebean_isEmbeddedNewOrDirty();
|
||||
default boolean _ebean_isEmbeddedNewOrDirty() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the intercept for this object.
|
||||
*/
|
||||
EntityBeanIntercept _ebean_getIntercept();
|
||||
default EntityBeanIntercept _ebean_getIntercept() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to _ebean_getIntercept() except it checks to see if the intercept
|
||||
@@ -66,7 +80,9 @@ public interface EntityBean extends Serializable {
|
||||
* frameworks that can't take into account our ebean fields.
|
||||
* </p>
|
||||
*/
|
||||
EntityBeanIntercept _ebean_intercept();
|
||||
default EntityBeanIntercept _ebean_intercept() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a field of an entity bean of this type.
|
||||
@@ -75,12 +91,16 @@ public interface EntityBean extends Serializable {
|
||||
* on entity beans. That means lazy loading and oldValues creation.
|
||||
* </p>
|
||||
*/
|
||||
void _ebean_setField(int fieldIndex, Object value);
|
||||
default void _ebean_setField(int fieldIndex, Object value) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the field value with interception.
|
||||
*/
|
||||
void _ebean_setFieldIntercept(int fieldIndex, Object value);
|
||||
default void _ebean_setFieldIntercept(int fieldIndex, Object value) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of a field from an entity bean of this type.
|
||||
@@ -89,11 +109,15 @@ public interface EntityBean extends Serializable {
|
||||
* on entity beans. That means lazy loading.
|
||||
* </p>
|
||||
*/
|
||||
Object _ebean_getField(int fieldIndex);
|
||||
default Object _ebean_getField(int fieldIndex) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field value with interception.
|
||||
*/
|
||||
Object _ebean_getFieldIntercept(int fieldIndex);
|
||||
default Object _ebean_getFieldIntercept(int fieldIndex) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
}
|
||||
+81
-81
@@ -1,6 +1,7 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.ValuePair;
|
||||
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
@@ -13,6 +14,8 @@ import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* This is the object added to every entity bean using byte code enhancement.
|
||||
@@ -29,6 +32,8 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
private static final int STATE_REFERENCE = 1;
|
||||
private static final int STATE_LOADED = 2;
|
||||
|
||||
private transient final ReentrantLock lock = new ReentrantLock(false);
|
||||
|
||||
private transient NodeUsageCollector nodeUsageCollector;
|
||||
|
||||
private transient PersistenceContext persistenceContext;
|
||||
@@ -39,6 +44,8 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
|
||||
private String ebeanServerName;
|
||||
|
||||
private boolean deletedFromCollection;
|
||||
|
||||
/**
|
||||
* The actual entity bean that 'owns' this intercept.
|
||||
*/
|
||||
@@ -79,14 +86,14 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
private static final byte FLAG_CHANGED_PROP = 2;
|
||||
|
||||
/**
|
||||
* Flags indicating if a property is a dirty embedded bean. Used to distingush
|
||||
* Flags indicating if a property is a dirty embedded bean. Used to distinguish
|
||||
* between an embedded bean being completely overwritten and one of its
|
||||
* embedded properties being made dirty.
|
||||
*/
|
||||
private static final byte FLAG_EMBEDDED_DIRTY = 4;
|
||||
|
||||
/**
|
||||
* Flags indicating if a property is a dirty embedded bean. Used to distingush
|
||||
* Flags indicating if a property is a dirty embedded bean. Used to distinguish
|
||||
* between an embedded bean being completely overwritten and one of its
|
||||
* embedded properties being made dirty.
|
||||
*/
|
||||
@@ -95,27 +102,29 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
private final byte[] flags;
|
||||
|
||||
private boolean fullyLoadedBean;
|
||||
|
||||
private boolean loadedFromCache;
|
||||
private Object[] origValues;
|
||||
|
||||
private Exception[] loadErrors;
|
||||
|
||||
private int lazyLoadProperty = -1;
|
||||
|
||||
private Object ownerId;
|
||||
private int sortOrder;
|
||||
|
||||
/**
|
||||
* Create a intercept with a given entity.
|
||||
* <p>
|
||||
* Refer to agent ProxyConstructor.
|
||||
* </p>
|
||||
*/
|
||||
public EntityBeanIntercept(Object ownerBean) {
|
||||
this.owner = (EntityBean) ownerBean;
|
||||
this.flags = new byte[owner._ebean_getPropertyNames().length];
|
||||
}
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - Constructor only for use by serialization frameworks.
|
||||
*/
|
||||
public EntityBeanIntercept() {
|
||||
this.owner = null;
|
||||
this.flags = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 'owning' entity bean.
|
||||
*/
|
||||
@@ -303,6 +312,22 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set true when the bean has been loaded from L2 bean cache.
|
||||
* The effect of this is that we should skip the cache if there
|
||||
* is subsequent lazy loading (bean cache partially populated).
|
||||
*/
|
||||
public void setLoadedFromCache(boolean loadedFromCache) {
|
||||
this.loadedFromCache = loadedFromCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this bean was loaded from L2 bean cache.
|
||||
*/
|
||||
public boolean isLoadedFromCache() {
|
||||
return loadedFromCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bean should be treated as readOnly. If a setter method
|
||||
* is called when it is readOnly an Exception is thrown.
|
||||
@@ -350,13 +375,11 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
/**
|
||||
* Set the loaded state to true.
|
||||
* <p>
|
||||
* Calls to setter methods after the bean is loaded can result in 'Old Values'
|
||||
* being created to support ConcurrencyMode.ALL
|
||||
* </p>
|
||||
* Calls to setter methods after the bean is loaded can result in
|
||||
* 'Old Values' being created.
|
||||
* <p>
|
||||
* Worth noting that this is also set after a insert/update. By doing so it
|
||||
* 'resets' the bean for making further changes and saving again.
|
||||
* </p>
|
||||
*/
|
||||
public void setLoaded() {
|
||||
this.state = STATE_LOADED;
|
||||
@@ -370,8 +393,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* When finished loading for lazy or refresh on an already partially populated
|
||||
* bean.
|
||||
* When finished loading for lazy or refresh on an already partially populated bean.
|
||||
*/
|
||||
public void setLoadedLazy() {
|
||||
this.state = STATE_LOADED;
|
||||
@@ -402,9 +424,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
|
||||
/**
|
||||
* Set true to turn off lazy loading.
|
||||
* <p>
|
||||
* Typically used to disable lazy loading on SQL based report beans.
|
||||
* </p>
|
||||
*/
|
||||
public void setDisableLazyLoad(boolean disableLazyLoad) {
|
||||
this.disableLazyLoad = disableLazyLoad;
|
||||
@@ -424,7 +443,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* Return true if the embedded bean is new or dirty and hence needs saving.
|
||||
*/
|
||||
public boolean isEmbeddedNewOrDirty(Object embeddedBean) {
|
||||
|
||||
if (embeddedBean == null) {
|
||||
// if it was previously set then the owning bean would
|
||||
// have oldValues containing the previous embedded bean
|
||||
@@ -432,7 +450,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
if (embeddedBean instanceof EntityBean) {
|
||||
return ((EntityBean) embeddedBean)._ebean_getIntercept().isNewOrDirty();
|
||||
|
||||
} else {
|
||||
// non-enhanced so must assume it is new and needs to be saved
|
||||
return true;
|
||||
@@ -450,8 +467,8 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the index position of a given property. Returns -1 if the property
|
||||
* can not be found.
|
||||
* Finds the index position of a given property. Returns -1 if the
|
||||
* property can not be found.
|
||||
*/
|
||||
public int findProperty(String propertyName) {
|
||||
String[] names = owner._ebean_getPropertyNames();
|
||||
@@ -474,7 +491,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of properties.s
|
||||
* Return the number of properties.
|
||||
*/
|
||||
public int getPropertyLength() {
|
||||
return owner._ebean_getPropertyNames().length;
|
||||
@@ -496,8 +513,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the property to be treated as unloaded. Used for properties initialised in default
|
||||
* constructor.
|
||||
* Set the property to be treated as unloaded. Used for properties initialised in default constructor.
|
||||
*/
|
||||
public void setPropertyUnloaded(int propertyIndex) {
|
||||
flags[propertyIndex] &= ~FLAG_LOADED_PROP;
|
||||
@@ -584,7 +600,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* For forced update on a 'New' bean set all the loaded properties to changed.
|
||||
*/
|
||||
public void setNewBeanForUpdate() {
|
||||
|
||||
for (int i = 0; i < flags.length; i++) {
|
||||
if ((flags[i] & FLAG_LOADED_PROP) != 0) {
|
||||
flags[i] |= FLAG_CHANGED_PROP;
|
||||
@@ -639,8 +654,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
for (int i = 0; i < len; i++) {
|
||||
if ((flags[i] & FLAG_CHANGED_PROP) != 0) {
|
||||
// the property has been changed on this bean
|
||||
String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i));
|
||||
props.add(propName);
|
||||
props.add((prefix == null ? getProperty(i) : prefix + getProperty(i)));
|
||||
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
|
||||
// an embedded property has been changed - recurse
|
||||
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
|
||||
@@ -653,12 +667,10 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* Return true if any of the given property names are dirty.
|
||||
*/
|
||||
public boolean hasDirtyProperty(Set<String> propertyNames) {
|
||||
|
||||
String[] names = owner._ebean_getPropertyNames();
|
||||
int len = getPropertyLength();
|
||||
for (int i = 0; i < len; i++) {
|
||||
if ((flags[i] & FLAG_CHANGED_PROP) != 0) {
|
||||
// the property has been changed on this bean
|
||||
if (propertyNames.contains(names[i])) {
|
||||
return true;
|
||||
}
|
||||
@@ -691,10 +703,9 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i));
|
||||
Object newVal = owner._ebean_getField(i);
|
||||
Object oldVal = getOrigValue(i);
|
||||
if (!areEqual(oldVal, newVal)) {
|
||||
if (notEqual(oldVal, newVal)) {
|
||||
dirtyValues.put(propName, new ValuePair(newVal, oldVal));
|
||||
}
|
||||
|
||||
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
|
||||
// an embedded property has been changed - recurse
|
||||
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
|
||||
@@ -713,10 +724,9 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
// the property has been changed on this bean
|
||||
Object newVal = owner._ebean_getField(i);
|
||||
Object oldVal = getOrigValue(i);
|
||||
if (!areEqual(oldVal, newVal)) {
|
||||
if (notEqual(oldVal, newVal)) {
|
||||
visitor.visit(i, newVal, oldVal);
|
||||
}
|
||||
|
||||
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
|
||||
// an embedded property has been changed - recurse
|
||||
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
|
||||
@@ -737,7 +747,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add and return a dirty property hash recursing into embedded beans.
|
||||
* Add and return a dirty property hash.
|
||||
*/
|
||||
private void addDirtyPropertyKey(StringBuilder sb) {
|
||||
if (sortOrder > 0) {
|
||||
@@ -772,7 +782,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
public boolean[] getLoaded() {
|
||||
boolean[] ret= new boolean[flags.length];
|
||||
boolean[] ret = new boolean[flags.length];
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
ret[i] = (flags[i] & FLAG_LOADED_PROP) != 0;
|
||||
}
|
||||
@@ -797,25 +807,28 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* Load the bean when it is a reference.
|
||||
*/
|
||||
protected void loadBean(int loadProperty) {
|
||||
|
||||
synchronized (this) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (beanLoader == null) {
|
||||
BeanLoader serverLoader = (BeanLoader) Ebean.getServer(ebeanServerName);
|
||||
if (serverLoader == null) {
|
||||
throw new PersistenceException("Server [" + ebeanServerName + "] was not found?");
|
||||
final Database database = DB.byName(ebeanServerName);
|
||||
if (database == null) {
|
||||
throw new PersistenceException("Database [" + ebeanServerName + "] was not found?");
|
||||
}
|
||||
|
||||
// For stand alone reference bean or after deserialisation lazy load
|
||||
// using the ebeanServer. Synchronise only on the bean.
|
||||
loadBeanInternal(loadProperty, serverLoader);
|
||||
loadBeanInternal(loadProperty, database.getPluginApi().beanLoader());
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
synchronized (beanLoader) {
|
||||
final Lock lock = beanLoader.lock();
|
||||
try {
|
||||
// Lazy loading using LoadBeanContext which supports batch loading
|
||||
// Synchronise on the beanLoader (a 'node' of the LoadBeanContext 'tree')
|
||||
loadBeanInternal(loadProperty, beanLoader);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,32 +836,24 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* Invoke the lazy loading. This method is synchronised externally.
|
||||
*/
|
||||
private void loadBeanInternal(int loadProperty, BeanLoader loader) {
|
||||
|
||||
if ((flags[loadProperty] & FLAG_LOADED_PROP) != 0) {
|
||||
// race condition where multiple threads calling preGetter concurrently
|
||||
return;
|
||||
}
|
||||
|
||||
if (lazyLoadFailure) {
|
||||
// failed when batch lazy loaded by another bean in the batch
|
||||
throw new EntityNotFoundException("(Lazy) loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted");
|
||||
}
|
||||
|
||||
if (lazyLoadProperty == -1) {
|
||||
|
||||
lazyLoadProperty = loadProperty;
|
||||
|
||||
if (nodeUsageCollector != null) {
|
||||
nodeUsageCollector.setLoadProperty(getProperty(lazyLoadProperty));
|
||||
}
|
||||
|
||||
loader.loadBean(this);
|
||||
|
||||
if (lazyLoadFailure) {
|
||||
// failed when lazy loading this bean
|
||||
throw new EntityNotFoundException("Lazy loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted.");
|
||||
}
|
||||
|
||||
// bean should be loaded and intercepting now. setLoaded() has
|
||||
// been called by the lazy loading mechanism
|
||||
}
|
||||
@@ -858,32 +863,31 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* Helper method to check if two objects are equal.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
protected boolean areEqual(Object obj1, Object obj2) {
|
||||
protected static boolean notEqual(Object obj1, Object obj2) {
|
||||
if (obj1 == null) {
|
||||
return (obj2 == null);
|
||||
return (obj2 != null);
|
||||
}
|
||||
if (obj2 == null) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (obj1 == obj2) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
if (obj1 instanceof BigDecimal) {
|
||||
// Use comparable for BigDecimal as equals
|
||||
// uses scale in comparison...
|
||||
if (obj2 instanceof BigDecimal) {
|
||||
Comparable com1 = (Comparable) obj1;
|
||||
return (com1.compareTo(obj2) == 0);
|
||||
|
||||
return (com1.compareTo(obj2) != 0);
|
||||
} else {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (obj1 instanceof URL) {
|
||||
// use the string format to determine if dirty
|
||||
return obj1.toString().equals(obj2.toString());
|
||||
return !obj1.toString().equals(obj2.toString());
|
||||
}
|
||||
return obj1.equals(obj2);
|
||||
return !obj1.equals(obj2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -894,6 +898,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
private void preGetterCallback(int propertyIndex) {
|
||||
PreGetterCallback preGetterCallback = this.preGetterCallback;
|
||||
if (preGetterCallback != null) {
|
||||
preGetterCallback.preGetterTrigger(propertyIndex);
|
||||
}
|
||||
@@ -923,25 +928,20 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* OneToMany and ManyToMany don't have any interception so just check for
|
||||
* PropertyChangeSupport.
|
||||
* OneToMany and ManyToMany only set loaded state.
|
||||
*/
|
||||
public void preSetterMany(boolean interceptField, int propertyIndex, Object oldValue, Object newValue) {
|
||||
|
||||
if (readOnly) {
|
||||
throw new IllegalStateException("This bean is readOnly");
|
||||
}
|
||||
|
||||
setLoadedProperty(propertyIndex);
|
||||
}
|
||||
|
||||
private void setChangedPropertyValue(int propertyIndex, boolean setDirtyState, Object origValue) {
|
||||
|
||||
if (readOnly) {
|
||||
throw new IllegalStateException("This bean is readOnly");
|
||||
}
|
||||
setChangedProperty(propertyIndex);
|
||||
|
||||
if (setDirtyState) {
|
||||
setOriginalValue(propertyIndex, origValue);
|
||||
setDirtyStatus();
|
||||
@@ -966,10 +966,9 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* the old values for use with ConcurrencyMode.ALL.
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, Object oldValue, Object newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (!areEqual(oldValue, newValue)) {
|
||||
} else if (notEqual(oldValue, newValue)) {
|
||||
setChangedPropertyValue(propertyIndex, intercept, oldValue);
|
||||
}
|
||||
}
|
||||
@@ -979,7 +978,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* Check for primitive boolean.
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, boolean oldValue, boolean newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (oldValue != newValue) {
|
||||
@@ -991,7 +989,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* Check for primitive int.
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, int oldValue, int newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (oldValue != newValue) {
|
||||
@@ -1003,7 +1000,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* long.
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, long oldValue, long newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (oldValue != newValue) {
|
||||
@@ -1015,7 +1011,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* double.
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, double oldValue, double newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (Double.compare(oldValue, newValue) != 0) {
|
||||
@@ -1027,7 +1022,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* float.
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, float oldValue, float newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (Float.compare(oldValue, newValue) != 0) {
|
||||
@@ -1039,7 +1033,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* short.
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, short oldValue, short newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (oldValue != newValue) {
|
||||
@@ -1051,7 +1044,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* char.
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, char oldValue, char newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (oldValue != newValue) {
|
||||
@@ -1063,7 +1055,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* byte.
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, byte oldValue, byte newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (oldValue != newValue) {
|
||||
@@ -1075,7 +1066,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* char[].
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, char[] oldValue, char[] newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (!Arrays.equals(oldValue, newValue)) {
|
||||
@@ -1087,7 +1077,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* byte[].
|
||||
*/
|
||||
public void preSetter(boolean intercept, int propertyIndex, byte[] oldValue, byte[] newValue) {
|
||||
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (!Arrays.equals(oldValue, newValue)) {
|
||||
@@ -1118,6 +1107,17 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the entity was deleted from a BeanCollection.
|
||||
*/
|
||||
public void setDeletedFromCollection(final boolean deletedFromCollection) {
|
||||
this.deletedFromCollection = deletedFromCollection;
|
||||
}
|
||||
|
||||
public boolean isOrphanDelete() {
|
||||
return deletedFromCollection && !isNew();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the load error that happened on this property.
|
||||
*/
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
/**
|
||||
* This exception is thrown, when the default implementation of EntityBean is not or not properly overwritten by enhancer.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
public class NotEnhancedException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,7 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Identifies a unique node of an object graph.
|
||||
@@ -85,8 +86,7 @@ public final class ObjectGraphNode implements Serializable {
|
||||
}
|
||||
|
||||
ObjectGraphNode e = (ObjectGraphNode) obj;
|
||||
//noinspection StringEquality
|
||||
return ((e.path == path) || (e.path != null && e.path.equals(path)))
|
||||
return (Objects.equals(e.path, path))
|
||||
&& e.originQueryPoint.equals(originQueryPoint);
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -16,7 +16,7 @@ public final class ObjectGraphOrigin implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 410937765287968708L;
|
||||
|
||||
private final CallStack callStack;
|
||||
private final CallOrigin callOrigin;
|
||||
|
||||
private final String beanType;
|
||||
|
||||
@@ -24,11 +24,11 @@ public final class ObjectGraphOrigin implements Serializable {
|
||||
|
||||
private final String key;
|
||||
|
||||
public ObjectGraphOrigin(int queryHash, CallStack callStack, String beanType) {
|
||||
this.callStack = callStack;
|
||||
public ObjectGraphOrigin(int queryHash, CallOrigin callOrigin, String beanType) {
|
||||
this.callOrigin = callOrigin;
|
||||
this.beanType = beanType;
|
||||
this.queryHash = queryHash;
|
||||
this.key = callStack.getOriginKey(queryHash);
|
||||
this.key = callOrigin.getOriginKey(queryHash);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,22 +49,22 @@ public final class ObjectGraphOrigin implements Serializable {
|
||||
/**
|
||||
* The call stack involved.
|
||||
*/
|
||||
public CallStack getCallStack() {
|
||||
return callStack;
|
||||
public CallOrigin getCallOrigin() {
|
||||
return callOrigin;
|
||||
}
|
||||
|
||||
public String getFirstStackElement() {
|
||||
return callStack.getFirstStackTraceElement().toString();
|
||||
public String getTopElement() {
|
||||
return callOrigin.getTopElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "key[" + key + "] type[" + beanType + "] " + callStack.getFirstStackTraceElement() + " ";
|
||||
return "key[" + key + "] type[" + beanType + "] " + callOrigin.getTopElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hc = 92821 * callStack.hashCode();
|
||||
int hc = 92821 * callOrigin.hashCode();
|
||||
hc = 92821 * hc + beanType.hashCode();
|
||||
hc = 92821 * hc + queryHash;
|
||||
return hc;
|
||||
@@ -82,6 +82,6 @@ public final class ObjectGraphOrigin implements Serializable {
|
||||
ObjectGraphOrigin e = (ObjectGraphOrigin) obj;
|
||||
return e.queryHash == queryHash
|
||||
&& e.beanType.equals(beanType)
|
||||
&& e.callStack.equals(callStack);
|
||||
&& e.callOrigin.equals(callOrigin);
|
||||
}
|
||||
}
|
||||
+16
@@ -61,6 +61,22 @@ public interface PersistenceContext {
|
||||
*/
|
||||
int size(Class<?> rootType);
|
||||
|
||||
/**
|
||||
* Return a copy of the Persistence context to use for large query iteration.
|
||||
*/
|
||||
PersistenceContext forIterate();
|
||||
|
||||
/**
|
||||
* Return a new Persistence context during iteration of large query result.
|
||||
*/
|
||||
PersistenceContext forIterateReset();
|
||||
|
||||
/**
|
||||
* Return true if the persistence context has grown and hit the 'reset limit'
|
||||
* during large query iteration.
|
||||
*/
|
||||
boolean resetLimit();
|
||||
|
||||
/**
|
||||
* Wrapper on a bean to also indicate if a bean has been deleted.
|
||||
* <p>
|
||||
@@ -0,0 +1,73 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import io.ebean.Database;
|
||||
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* BeanLoader used when single beans are loaded (which is usually not ideal / N+1).
|
||||
*/
|
||||
public abstract class SingleBeanLoader implements BeanLoader {
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock(false);
|
||||
|
||||
protected final Database database;
|
||||
|
||||
SingleBeanLoader(Database database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return database.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock lock() {
|
||||
lock.lock();
|
||||
return lock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Single bean lazy loaded when bean from L2 cache.
|
||||
*/
|
||||
public static class L2 extends SingleBeanLoader {
|
||||
public L2(Database database) {
|
||||
super(database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBean(EntityBeanIntercept ebi) {
|
||||
database.getPluginApi().loadBeanL2(ebi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Single bean lazy loaded when a reference bean.
|
||||
*/
|
||||
public static class Ref extends SingleBeanLoader {
|
||||
public Ref(Database database) {
|
||||
super(database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBean(EntityBeanIntercept ebi) {
|
||||
database.getPluginApi().loadBeanRef(ebi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Single bean lazy loaded when a reference bean.
|
||||
*/
|
||||
public static class Dflt extends SingleBeanLoader {
|
||||
public Dflt(Database database) {
|
||||
super(database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBean(EntityBeanIntercept ebi) {
|
||||
database.getPluginApi().loadBean(ebi);
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -1,5 +1,7 @@
|
||||
package io.ebean.cache;
|
||||
|
||||
import io.ebean.meta.MetricVisitor;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -79,4 +81,11 @@ public interface ServerCache {
|
||||
* @param reset if true the statistics are reset.
|
||||
*/
|
||||
ServerCacheStatistics getStatistics(boolean reset);
|
||||
|
||||
/**
|
||||
* Visit the metrics for the cache.
|
||||
*/
|
||||
default void visit(MetricVisitor visitor) {
|
||||
// do nothing by default
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -9,13 +9,15 @@ public class ServerCacheConfig {
|
||||
|
||||
private final ServerCacheType type;
|
||||
private final String cacheKey;
|
||||
private final String shortName;
|
||||
private final ServerCacheOptions cacheOptions;
|
||||
private final CurrentTenantProvider tenantProvider;
|
||||
private final QueryCacheEntryValidate queryCacheEntryValidate;
|
||||
|
||||
public ServerCacheConfig(ServerCacheType type, String cacheKey, ServerCacheOptions cacheOptions, CurrentTenantProvider tenantProvider, QueryCacheEntryValidate queryCacheEntryValidate) {
|
||||
public ServerCacheConfig(ServerCacheType type, String cacheKey, String shortName, ServerCacheOptions cacheOptions, CurrentTenantProvider tenantProvider, QueryCacheEntryValidate queryCacheEntryValidate) {
|
||||
this.type = type;
|
||||
this.cacheKey = cacheKey;
|
||||
this.shortName = shortName;
|
||||
this.cacheOptions = cacheOptions;
|
||||
this.tenantProvider = tenantProvider;
|
||||
this.queryCacheEntryValidate = queryCacheEntryValidate;
|
||||
@@ -35,6 +37,13 @@ public class ServerCacheConfig {
|
||||
return cacheKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the short name for the cache.
|
||||
*/
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the tuning options.
|
||||
*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user