Skip to content

Commit beb0461

Browse files
committed
For #220, detect unexpected OneToMany initialisation cases
Previously didn't account for Collections.EMPTY_LIST (which is field bytecode rather than method bytecode). Also account for initialising as an unsupported List, Set, Map implementation like ebeans own BeanList. The expected implementations are ArrayList, LinkedHashSet, LinkedHashMap.
1 parent 12cff17 commit beb0461

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ 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)) {
192+
if (meta.isConsumeInitMany(name) && unsupportedInitialisation()) {
193193
// a OneToMany/ManyToMany is initialised in an unsupported manor
194194
meta.addUnsupportedInitMany(name);
195195
flush();
@@ -221,6 +221,15 @@ boolean consumeVisitFieldInsn(int opcode, String owner, String name, String desc
221221
return false;
222222
}
223223

224+
/**
225+
* Return true when a OneToMany or ManyToMany is not initialised in a supported manor.
226+
*/
227+
private boolean unsupportedInitialisation() {
228+
return state == State.MAYBE_UNSUPPORTED
229+
|| state == State.UNSET // proceeded by GETSTATIC field bytecode like Collections.EMPTY_LIST
230+
|| state == State.INVOKE_SPECIAL && !isConsumeManyType(); // e.g. new BeanList()
231+
}
232+
224233
boolean consumeVisitLabel(Label label) {
225234
if (state == State.KT_CHECKCAST) {
226235
codes.add(new DeferredLabel(label));

test/src/test/java/test/model/WithInitialisedCollections2.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public class WithInitialisedCollections2 extends BaseEntity {
2626
@OneToMany(cascade = CascadeType.PERSIST)
2727
Map<Long,Contact> mapCollEmpty = Collections.emptyMap();
2828

29+
// @OneToMany final List<Contact> listCollNotValidInitialisation0 = new io.ebean.common.BeanList<>();
30+
// @OneToMany final List<Contact> listCollNotValidInitialisation1 = Collections.EMPTY_LIST;
31+
// @OneToMany final List<Contact> listCollNotValidInitialisation2 = List.of(new Contact("junk"));
32+
// @OneToMany final List<Contact> listCollNotValidInitialisation3 = Collections.unmodifiableList(Collections.emptyList());
33+
2934
@Transient
3035
List<String> transientList = List.of();
3136
@Transient

0 commit comments

Comments
 (0)