├── .gitignore
├── .travis.yml
├── .travis
└── maven-settings.xml
├── LICENSE
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── io
│ └── vavr
│ └── hibernate
│ └── userstype
│ ├── ListUserType.java
│ └── PersistentList.java
└── test
└── java
└── io
└── vavr
└── hibernate
└── ListUserTypeTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | .idea
3 | *.iml
4 | *.ipr
5 | *.iws
6 | ### Java template
7 | # Compiled class file
8 | *.class
9 |
10 | # Log file
11 | *.log
12 |
13 | # BlueJ files
14 | *.ctxt
15 |
16 | # Mobile Tools for Java (J2ME)
17 | .mtj.tmp/
18 |
19 | # Package Files #
20 | *.jar
21 | *.war
22 | *.ear
23 | *.zip
24 | *.tar.gz
25 | *.rar
26 |
27 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
28 | hs_err_pid*
29 | ### JetBrains template
30 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
31 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
32 |
33 | # User-specific stuff:
34 | .idea/**/workspace.xml
35 | .idea/**/tasks.xml
36 | .idea/dictionaries
37 |
38 | # Sensitive or high-churn files:
39 | .idea/**/dataSources/
40 | .idea/**/dataSources.ids
41 | .idea/**/dataSources.xml
42 | .idea/**/dataSources.local.xml
43 | .idea/**/sqlDataSources.xml
44 | .idea/**/dynamic.xml
45 | .idea/**/uiDesigner.xml
46 |
47 | # Gradle:
48 | .idea/**/gradle.xml
49 | .idea/**/libraries
50 |
51 | # Mongo Explorer plugin:
52 | .idea/**/mongoSettings.xml
53 |
54 | ## File-based project format:
55 |
56 | ## Plugin-specific files:
57 |
58 | # IntelliJ
59 | /out/
60 |
61 | # mpeltonen/sbt-idea plugin
62 | .idea_modules/
63 |
64 | # JIRA plugin
65 | atlassian-ide-plugin.xml
66 |
67 | # Crashlytics plugin (for Android Studio and IntelliJ)
68 | com_crashlytics_export_strings.xml
69 | crashlytics.properties
70 | crashlytics-build.properties
71 | fabric.properties
72 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 | env:
5 | global:
6 | - secure: D8Z2pmvfy0LETBW5A6xzdU/Q8dEkbVAptbofWZIpHEl4dWC6vVux3A5MeRIXp6Sv5n/Vyw4pIh+dXcUrrLtofhLksTLIEgeNpG6hC+ctMYMxW63U2skIxa6RQ8iZy5/qQ9btJH3hd4hJI3u2sQ2NgHpw/KCj1sRrT8aIrS9QQl4zxxLd8D8HPUlr3O/eV1Ik38quCPmmrp/6jRJnZnE1Y3IcNqt/L0CLsZwqued6WyqWBU/2yskGxmij5i88RPgxN1oau6HUtPW8lqJhwdnTOgi9/t9kDkItopPC25A6gSGwwI75gF1jvWe95aQQfqLwHnOZcjEEBs3836ibQT5PPTr9vtKLssH35uM22pAWIlP38zilOIVN4Jy3nYC983ef7ZtBLuBFBatmOUBYOrlFN4GdlVPUOcbZFsBnjQnDoSADJ+fDt6Q/WJ2knudfc82kle0Jul8fIKP5OIGLk1ZhhuBYkbM6k8l3offk/cRIhVI5D94zm2UJkw+8MAlP6ffcPNMUzCU9YofaB0lX3j5/JKwntph27VnNUsplsUtM0uOEtN+4VuzdzAXDnm1yp4fGObffrMUJ9coG+kEBYaKFoLgFoVv1H76Xn1FLWtbqBOnC6Se5FPoxYVD2eYMjNRuEP9sYs63jS0oYjWj+Z2z1rkH26BgyGcCZxCj7qTzvTwE=
7 | - secure: DTfPB0fMpchGnbeV5YVevVQBoqow1WCeSZqgjKigsVgkKTFhuX03Wnbjce7E669p2vioPclxrF6jvjegDZCexIjUYNRZhfNZtvaZ6/kzwOC9vlC9b+5WJ6XSG6gm7YZaQ2TP353c8bqBSyVW2LvECtwZZxM3x6pt8zA2UX100uh/+0Ftc3QbBoBXZkgaXfCT84P/OO52hPuZZl04u+TJabrwt3TPxRUIcxTrGUnW37wOPxyYt6qcFZplAmjorm6vFIcE0FNH90yViqEp3rKBtQGgDW0XnmoTYLRCEDDdRmTyGFoOjjnpZuaA41iiUJx6F3H63zAQOpB8mefjvYGKcnvIVHTHWfPOwNycSiATQ9g8QV5Z3y6HE+Kk5wDcL/USiOl4tn651s4eY+tE2sswpRyMfQa/f6x73xYT0Wqa22Xss4uzLtVJhxcZIku8pxDSJg40XQxSUXwuwfU3OJvNjsKVPjXnZ3QYrvQN7A6ZEDRw60BLQ+XVvlHSdLAeWPbtUWeUc1ke/x7QhTGIskkGlvV9AlW6LQDkfX5YwjQ9ZYCyAmfSjmN4J01oBQbbj+/XoS1iIna7VpWEEPbMw6sG+CF3jyk14EwmU2l8G3ZxtXBkzzCH5joIOTQZh8iUZ1BxTqBWlExHlcaUHJxG12udc/MLzkKUDIcOEIOlkzuwfhU=
8 | before_install:
9 | - sudo apt-get update
10 | - sudo apt-get install --only-upgrade -y oracle-java8-installer
11 | - pip install --user codecov
12 | script:
13 | - mvn clean test -B
14 | - mvn clean test -B -Dfasterxml.version=2.8.4
15 | after_success:
16 | - codecov
17 | - mvn clean deploy -DskipTests --settings .travis/maven-settings.xml
--------------------------------------------------------------------------------
/.travis/maven-settings.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | sonatype-nexus-snapshots
13 | ${env.SONATYPE_USER}
14 | ${env.SONATYPE_PASS}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2014-2017 Vavr, http://vavr.io
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Hibernate module for Vavr
2 | -
3 |
4 | This is currently a total WIP.
5 | Initial goals
6 |
7 | 1. Get a `List` wiring in via a UserType
8 | 2. Get an `Option` wired in via a UserType
9 | 3. Auto-support `List` through registration.
10 | 4. Auto-support `Option` through registration.
11 |
12 |
13 | Notes:
14 | -
15 | `PersistentList` must be one of type vavr `List` and be of type `PersistentCollection`
16 | to be supported by hibernate. Currently implementation is super verbose because it must delegate
17 | so many methods. Lombok `@Delegate` doesn't really help because of it's limitations.
18 | Lombok `@Delegate` only delegates methods for 1 level of hierarchy and `List` has at least 4
19 | and implements multiple interfaces.
20 |
21 | `TypeDescriptor` is the mechanism by which hibernate auto-registers it's
22 | type marshalling scheme.
23 |
24 | Current test in place fails as planned. Get that to work and we are have something.
25 |
26 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | org.sonatype.oss
6 | oss-parent
7 | 9
8 |
9 |
10 | io.vavr
11 | vavr-hibernate
12 | 1.0.0-SNAPSHOT
13 | jar
14 | http://vavr.io
15 | Vavr-Hibernate
16 | Hibernate datatype module for Vavr.io
17 |
18 |
19 | The Apache Software License, Version 2.0
20 | http://www.apache.org/licenses/LICENSE-2.0.txt
21 | repo
22 |
23 |
24 |
25 | scm:git:git@github.com:vavr-io/vavr-hibernate.git
26 | scm:git:git@github.com:vavr-io/vavr-hibernate.git
27 | git@github.com:vavr-io/vavr-hibernate.git
28 | HEAD
29 |
30 |
31 |
32 |
33 | cbongiorno
34 | Christian Bongiorno
35 | christian.bongiorno@gmail.com
36 |
37 |
38 |
39 |
40 | UTF-8
41 | 1.8
42 | 4.12
43 | 1.0.0-SNAPSHOT
44 | 3.2
45 | 2.7.2
46 | 4.0.0
47 | 0.7.5.201505241946
48 | 1.5
49 | 2.5.1
50 | 2.1
51 | 1.5.3.RELEASE
52 |
53 |
54 |
55 |
56 | io.vavr
57 | vavr
58 | ${vavr.version}
59 |
60 |
61 |
62 | junit
63 | junit
64 | ${junit.version}
65 | test
66 |
67 |
68 | org.assertj
69 | assertj-core
70 | 2.2.0
71 | test
72 |
73 |
74 |
75 | org.projectlombok
76 | lombok
77 | 1.16.16
78 | provided
79 |
80 |
81 | org.hibernate
82 | hibernate-core
83 | 5.2.10.Final
84 |
85 |
86 | org.springframework.boot
87 | spring-boot-autoconfigure
88 | ${spring-boot.version}
89 | test
90 |
91 |
92 | org.springframework.boot
93 | spring-boot-test-autoconfigure
94 | ${spring-boot.version}
95 | test
96 |
97 |
98 | org.springframework
99 | spring-test
100 | 4.3.4.RELEASE
101 | test
102 |
103 |
104 | org.springframework
105 | spring-tx
106 | 4.3.4.RELEASE
107 | test
108 |
109 |
110 | org.springframework.boot
111 | spring-boot-starter-data-jpa
112 |
113 |
114 | org.hibernate
115 | hibernate-entitymanager
116 |
117 |
118 | ${spring-boot.version}
119 | test
120 |
121 |
122 |
123 | org.hsqldb
124 | hsqldb
125 | test
126 | 2.3.1
127 |
128 |
129 |
130 |
131 |
132 |
133 | org.apache.maven.plugins
134 | maven-compiler-plugin
135 | ${maven.compiler.version}
136 |
137 | ${java.version}
138 | ${java.version}
139 | true
140 | true
141 |
142 | -Xlint:all
143 | -Werror
144 |
145 | -Xlint:-processing
146 |
147 |
148 |
149 |
150 | org.codehaus.mojo
151 | versions-maven-plugin
152 | ${maven.versions.version}
153 |
154 |
155 |
156 |
157 |
158 | org.apache.maven.plugins
159 | maven-release-plugin
160 | ${maven.release.version}
161 |
162 |
163 | forked-path
164 | false
165 |
166 | ${arguments} -Psonatype-oss-release
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | ci
176 |
177 |
178 | env.CI
179 |
180 |
181 |
182 |
183 |
184 | org.jacoco
185 | jacoco-maven-plugin
186 | ${maven.jacoco.version}
187 |
188 |
189 |
190 | prepare-agent
191 |
192 |
193 |
194 | report
195 | test
196 |
197 | report
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 | release-sign-artifacts
208 |
209 |
210 |
211 | performRelease
212 | true
213 |
214 |
215 |
216 |
217 |
218 | org.apache.maven.plugins
219 | maven-gpg-plugin
220 | ${maven.gpg.version}
221 |
222 |
223 | sign-artifacts
224 | verify
225 |
226 | sign
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
--------------------------------------------------------------------------------
/src/main/java/io/vavr/hibernate/userstype/ListUserType.java:
--------------------------------------------------------------------------------
1 | package io.vavr.hibernate.userstype;
2 |
3 | import io.vavr.collection.List;
4 | import java.util.Iterator;
5 | import java.util.Map;
6 | import org.hibernate.HibernateException;
7 | import org.hibernate.collection.spi.PersistentCollection;
8 | import org.hibernate.engine.spi.SharedSessionContractImplementor;
9 | import org.hibernate.persister.collection.CollectionPersister;
10 | import org.hibernate.usertype.UserCollectionType;
11 |
12 | /**
13 | * @author cbongiorno on 7/3/17.
14 | */
15 | public class ListUserType implements UserCollectionType {
16 |
17 | @Override
18 | public PersistentCollection instantiate(SharedSessionContractImplementor session,
19 | CollectionPersister persister) throws HibernateException {
20 | return null;
21 | }
22 |
23 | @Override
24 | public PersistentCollection wrap(SharedSessionContractImplementor session, Object collection) {
25 | return null;
26 | }
27 |
28 | @Override
29 | public Iterator getElementsIterator(Object collection) {
30 | return ((List)collection).iterator();
31 | }
32 |
33 | @Override
34 | public boolean contains(Object collection, Object entity) {
35 | return ((List)collection).contains(entity);
36 | }
37 |
38 | @Override
39 | public Object indexOf(Object collection, Object entity) {
40 | return ((List)collection).indexOf(entity);
41 | }
42 |
43 | @Override
44 | public Object replaceElements(Object original, Object target, CollectionPersister persister,
45 | Object owner, Map copyCache, SharedSessionContractImplementor session)
46 | throws HibernateException {
47 | return null;
48 | }
49 |
50 | @Override
51 | public Object instantiate(int anticipatedSize) {
52 | return List.empty();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/io/vavr/hibernate/userstype/PersistentList.java:
--------------------------------------------------------------------------------
1 | package io.vavr.hibernate.userstype;
2 |
3 | import io.vavr.CheckedFunction0;
4 | import io.vavr.Function1;
5 | import io.vavr.PartialFunction;
6 | import io.vavr.Tuple;
7 | import io.vavr.Tuple1;
8 | import io.vavr.Tuple2;
9 | import io.vavr.Tuple3;
10 | import io.vavr.collection.Array;
11 | import io.vavr.collection.CharSeq;
12 | import io.vavr.collection.List;
13 | import io.vavr.collection.Map;
14 | import io.vavr.collection.PriorityQueue;
15 | import io.vavr.collection.Queue;
16 | import io.vavr.collection.Seq;
17 | import io.vavr.collection.SortedMap;
18 | import io.vavr.collection.SortedSet;
19 | import io.vavr.collection.Tree;
20 | import io.vavr.collection.Vector;
21 | import io.vavr.control.Either;
22 | import io.vavr.control.Option;
23 | import io.vavr.control.Try;
24 | import io.vavr.control.Validation;
25 | import java.io.PrintStream;
26 | import java.io.PrintWriter;
27 | import java.io.Serializable;
28 | import java.sql.ResultSet;
29 | import java.sql.SQLException;
30 | import java.util.Collection;
31 | import java.util.Comparator;
32 | import java.util.Iterator;
33 | import java.util.Objects;
34 | import java.util.Optional;
35 | import java.util.Set;
36 | import java.util.Spliterator;
37 | import java.util.concurrent.CompletableFuture;
38 | import java.util.function.BiConsumer;
39 | import java.util.function.BiFunction;
40 | import java.util.function.BiPredicate;
41 | import java.util.function.Consumer;
42 | import java.util.function.Function;
43 | import java.util.function.Predicate;
44 | import java.util.function.Supplier;
45 | import java.util.stream.Collector;
46 | import java.util.stream.Stream;
47 | import lombok.EqualsAndHashCode;
48 | import org.hibernate.HibernateException;
49 | import org.hibernate.collection.internal.AbstractPersistentCollection;
50 | import org.hibernate.engine.spi.SharedSessionContractImplementor;
51 | import org.hibernate.loader.CollectionAliases;
52 | import org.hibernate.persister.collection.CollectionPersister;
53 | import org.hibernate.type.Type;
54 |
55 | /**
56 | * @author cbongiorno on 7/5/17.
57 | */
58 | @EqualsAndHashCode(of = "delegate")
59 | public class PersistentList extends AbstractPersistentCollection implements List {
60 |
61 |
62 | private List delegate = List.empty();
63 |
64 |
65 | public PersistentList(SharedSessionContractImplementor session) {
66 | super(session);
67 | }
68 |
69 | public PersistentList(SharedSessionContractImplementor session, List delegate) {
70 | super(session);
71 | this.delegate = delegate;
72 |
73 | }
74 |
75 | @Override
76 | public boolean empty() {
77 | return delegate.isEmpty();
78 | }
79 |
80 | @Override
81 | public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
82 | return null;
83 | }
84 |
85 | @Override
86 | public void initializeFromCache(CollectionPersister persister, Serializable disassembled,
87 | Object owner) {
88 | System.out.println();
89 | }
90 |
91 | @Override
92 | public Iterator entries(CollectionPersister persister) {
93 | return delegate.iterator();
94 | }
95 |
96 | private transient List loadingEntries;
97 |
98 | @Override
99 | public Object readFrom(ResultSet rs, CollectionPersister role, CollectionAliases descriptor,
100 | Object owner) throws HibernateException, SQLException {
101 |
102 | final Object element = role
103 | .readElement(rs, owner, descriptor.getSuffixedElementAliases(), getSession());
104 | if (element != null) {
105 | final Object index = role.readIndex(rs, descriptor.getSuffixedIndexAliases(), getSession());
106 | loadingEntries = Option.of(loadingEntries).filter(Objects::nonNull).getOrElse(List.empty());
107 | loadingEntries = loadingEntries.append(Tuple.of(index, element));
108 | }
109 | return element;
110 | }
111 |
112 | @Override
113 | public Object getIndex(Object entry, int i, CollectionPersister persister) {
114 | return delegate.get(i);
115 | }
116 |
117 | @Override
118 | public Object getElement(Object entry) {
119 | return entry;
120 | }
121 |
122 | @Override
123 | public Object getSnapshotElement(Object entry, int i) {
124 | // supposed to copy this element.
125 | return entry;
126 | }
127 |
128 | @Override
129 | @SuppressWarnings("unchecked")
130 | public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
131 | this.delegate = (List) persister.getCollectionType().instantiate(anticipatedSize);
132 |
133 | }
134 |
135 | @Override
136 | public boolean equalsSnapshot(CollectionPersister persister) {
137 | return false;
138 | }
139 |
140 | @Override
141 | public boolean isSnapshotEmpty(Serializable snapshot) {
142 | return ((List) snapshot).isEmpty();
143 | }
144 |
145 | @Override
146 | public Serializable disassemble(CollectionPersister persister) {
147 | return delegate.map(v -> persister.getElementType().disassemble(v, getSession(), null));
148 | }
149 |
150 | @Override
151 | public Serializable getSnapshot(CollectionPersister persister) {
152 | return delegate.map(v -> persister.getElementType().deepCopy(v, persister.getFactory()));
153 | }
154 |
155 | @Override
156 | @SuppressWarnings("unchecked")
157 | public boolean entryExists(Object entry, int i) {
158 | return delegate.contains((T) entry);
159 | }
160 |
161 | @Override
162 | public boolean needsInserting(Object entry, int i, Type elemType) {
163 | return !delegate.get(i).equals(entry);
164 | }
165 |
166 | @Override
167 | public boolean needsUpdating(Object entry, int i, Type elemType) {
168 | return false;
169 | }
170 |
171 | @Override
172 | public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) {
173 | return null;
174 | }
175 |
176 | @Override
177 | public boolean isWrapper(Object collection) {
178 | return false;
179 | }
180 |
181 |
182 | @Override
183 | public T fold(T zero, BiFunction super T, ? super T, ? extends T> combine) {
184 | return delegate.fold(zero, combine);
185 | }
186 |
187 | @Override
188 | public boolean isMemoized() {
189 | return delegate.isMemoized();
190 | }
191 |
192 |
193 | @Override
194 | public int indexOfSlice(Iterable extends T> that, int from) {
195 | return delegate.indexOfSlice(that, from);
196 | }
197 |
198 | @Override
199 | public int indexWhere(Predicate super T> predicate, int from) {
200 | return delegate.indexWhere(predicate, from);
201 | }
202 |
203 |
204 | @Override
205 | public T apply(Integer index) {
206 | return delegate.apply(index);
207 | }
208 |
209 | @Override
210 | public T reduce(BiFunction super T, ? super T, ? extends T> op) {
211 | return delegate.reduce(op);
212 | }
213 |
214 | @Override
215 | public boolean isDefinedAt(Integer index) {
216 | return delegate.isDefinedAt(index);
217 | }
218 |
219 |
220 | @Override
221 | public int lastIndexOfSlice(Iterable extends T> that, int end) {
222 | return delegate.lastIndexOfSlice(that, end);
223 | }
224 |
225 |
226 | @Override
227 | public int lastIndexWhere(Predicate super T> predicate, int end) {
228 | return delegate.lastIndexWhere(predicate, end);
229 | }
230 |
231 | @Override
232 | public Option reduceOption(BiFunction super T, ? super T, ? extends T> op) {
233 | return delegate.reduceOption(op);
234 | }
235 |
236 |
237 | @Override
238 | public boolean isAsync() {
239 | return delegate.isAsync();
240 | }
241 |
242 |
243 | @Override
244 | public boolean isEmpty() {
245 | return delegate.isEmpty();
246 | }
247 |
248 |
249 | @Override
250 | public boolean isLazy() {
251 | return delegate.isLazy();
252 | }
253 |
254 | @Override
255 | public Option