Skip to content

Commit af1a203

Browse files
committed
Add back support for List.of() and Collections.emptyList() as initialisation for OneToMany etc
The thinking is that many folks are not reading the JPA spec, and there are some folks "suggesting" to initialise OneToMany collections with Collections.emptyList() ... even though it isn't as per JPA spec. Hmmm.
1 parent 20b1bc4 commit af1a203

File tree

1 file changed

+43
-42
lines changed

1 file changed

+43
-42
lines changed

ebean-agent/src/main/java/io/ebean/enhance/entity/ConstructorDeferredCode.java

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -132,24 +132,24 @@ boolean deferVisitMethodInsn(int opcode, String owner, String name, String desc,
132132
return true;
133133
}
134134
if (opcode == INVOKESTATIC && stateAload()) {
135-
if (kotlinEmptyList(owner, name, desc)) { // emptyList(owner, name, desc) ||
135+
if (kotlinEmptyList(owner, name, desc) || emptyList(owner, name, desc)) {
136136
codes.add(new NoArgInit(opcode, owner, name, desc, itf));
137137
state = State.EMPTY;
138138
stateInitialiseType = "java/util/ArrayList";
139139
return true;
140140
}
141-
// if (emptySet(owner, name, desc)) {
142-
// codes.add(new NoArgInit(opcode, owner, name, desc, itf));
143-
// state = State.EMPTY;
144-
// stateInitialiseType = "java/util/LinkedHashSet";
145-
// return true;
146-
// }
147-
// if (emptyMap(owner, name, desc)) {
148-
// codes.add(new NoArgInit(opcode, owner, name, desc, itf));
149-
// state = State.EMPTY;
150-
// stateInitialiseType = "java/util/LinkedHashMap";
151-
// return true;
152-
// }
141+
if (emptySet(owner, name, desc)) {
142+
codes.add(new NoArgInit(opcode, owner, name, desc, itf));
143+
state = State.EMPTY;
144+
stateInitialiseType = "java/util/LinkedHashSet";
145+
return true;
146+
}
147+
if (emptyMap(owner, name, desc)) {
148+
codes.add(new NoArgInit(opcode, owner, name, desc, itf));
149+
state = State.EMPTY;
150+
stateInitialiseType = "java/util/LinkedHashMap";
151+
return true;
152+
}
153153
}
154154
flush();
155155
state = State.MAYBE_UNSUPPORTED;
@@ -160,23 +160,23 @@ private boolean isNoArgInit(String name, String desc) {
160160
return name.equals(INIT) && desc.equals(NOARG_VOID);
161161
}
162162

163-
// private boolean emptyList(String owner, String name, String desc) {
164-
// return desc.equals("()Ljava/util/List;")
165-
// && ((owner.equals("java/util/List") && name.equals("of"))
166-
// || (owner.equals("java/util/Collections") && name.equals("emptyList")));
167-
// }
168-
//
169-
// private boolean emptySet(String owner, String name, String desc) {
170-
// return desc.equals("()Ljava/util/Set;")
171-
// && ((owner.equals("java/util/Set") && name.equals("of"))
172-
// || (owner.equals("java/util/Collections") && name.equals("emptySet")));
173-
// }
174-
//
175-
// private boolean emptyMap(String owner, String name, String desc) {
176-
// return desc.equals("()Ljava/util/Map;")
177-
// && ((owner.equals("java/util/Map") && name.equals("of"))
178-
// || (owner.equals("java/util/Collections") && name.equals("emptyMap")));
179-
// }
163+
private boolean emptyList(String owner, String name, String desc) {
164+
return desc.equals("()Ljava/util/List;")
165+
&& ((owner.equals("java/util/List") && name.equals("of"))
166+
|| (owner.equals("java/util/Collections") && name.equals("emptyList")));
167+
}
168+
169+
private boolean emptySet(String owner, String name, String desc) {
170+
return desc.equals("()Ljava/util/Set;")
171+
&& ((owner.equals("java/util/Set") && name.equals("of"))
172+
|| (owner.equals("java/util/Collections") && name.equals("emptySet")));
173+
}
174+
175+
private boolean emptyMap(String owner, String name, String desc) {
176+
return desc.equals("()Ljava/util/Map;")
177+
&& ((owner.equals("java/util/Map") && name.equals("of"))
178+
|| (owner.equals("java/util/Collections") && name.equals("emptyMap")));
179+
}
180180

181181
private boolean kotlinEmptyList(String owner, String name, String desc) {
182182
return owner.equals("kotlin/collections/CollectionsKt")
@@ -189,19 +189,20 @@ private boolean kotlinEmptyList(String owner, String name, String desc) {
189189
*/
190190
boolean consumeVisitFieldInsn(int opcode, String owner, String name, String desc) {
191191
if (opcode == PUTFIELD) {
192+
if (state == State.MAYBE_UNSUPPORTED && meta.isConsumeInitMany(name)) {
193+
// a OneToMany/ManyToMany is initialised in an unsupported manor
194+
meta.addUnsupportedInitMany(name);
195+
flush();
196+
return false;
197+
}
192198
if (stateConsumeDeferred()) {
193-
if (meta.isConsumeInitMany(name)) {
194-
if (isConsumeManyType()) {
195-
if (meta.isLog(3)) {
196-
meta.log("... consumed init of many: " + name);
197-
}
198-
state = State.UNSET;
199-
codes.clear();
200-
return true;
201-
} else {
202-
// a OneToMany/ManyToMany is initialised in an unsupported manor
203-
meta.addUnsupportedInitMany(name);
199+
if (meta.isConsumeInitMany(name) && isConsumeManyType()) {
200+
if (meta.isLog(3)) {
201+
meta.log("... consumed init of many: " + name);
204202
}
203+
state = State.UNSET;
204+
codes.clear();
205+
return true;
205206
} else if (meta.isInitTransient(name)) {
206207
// keep the initialisation code for transient to 'replay'
207208
// it when adding a default constructor if needed
@@ -271,7 +272,7 @@ private boolean stateInvokeSpecial() {
271272
}
272273

273274
private boolean stateConsumeDeferred() {
274-
return state == State.INVOKE_SPECIAL || state == State.KT_CHECKCAST || state == State.EMPTY || state == State.MAYBE_UNSUPPORTED;
275+
return state == State.INVOKE_SPECIAL || state == State.KT_CHECKCAST || state == State.EMPTY;
275276
}
276277

277278
/**

0 commit comments

Comments
 (0)