-
-
Notifications
You must be signed in to change notification settings - Fork 260
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#3173 - BeanSet lazy loading / Too many DataSource connections used
- The error reported was that a DataSource connection pool maxed out - The symptom was that there was an additional lazy loading queries invoked via the hashCode/equals implementation of ManyToMany Set. - The fix is for BeanSet init() to lazy load with onlyIds = false, that avoids the extra lazy loading query from being executed
- Loading branch information
Showing
4 changed files
with
131 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package org.tests.sets; | ||
|
||
import javax.persistence.Entity; | ||
import javax.persistence.Id; | ||
import javax.persistence.ManyToMany; | ||
import java.util.*; | ||
|
||
@Entity | ||
public class M2MDepart { | ||
|
||
@Id | ||
private UUID id; | ||
|
||
private final String name; | ||
|
||
@ManyToMany | ||
private final Set<M2MEmp> employees = new LinkedHashSet<>(); | ||
|
||
public M2MDepart(String name) { | ||
this.name = name; | ||
} | ||
|
||
public void addEmployee(M2MEmp employee) { | ||
this.employees.add(employee); | ||
} | ||
|
||
public UUID getId() { | ||
return id; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public Set<M2MEmp> employees() { | ||
return employees; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package org.tests.sets; | ||
|
||
import javax.persistence.*; | ||
import java.util.HashSet; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import java.util.UUID; | ||
|
||
@Entity | ||
public class M2MEmp { | ||
|
||
@Id | ||
private UUID id; | ||
|
||
private final String code; | ||
|
||
private String name; | ||
|
||
@ManyToMany | ||
@JoinTable(name="m2m_dept_emp", | ||
joinColumns= | ||
@JoinColumn(name="employee_id", referencedColumnName="id"), | ||
inverseJoinColumns= | ||
@JoinColumn(name="department_id", referencedColumnName="id") | ||
) | ||
private final Set<M2MDepart> departments = new HashSet<>(); | ||
|
||
public M2MEmp(String name, String code) { | ||
this.name = name; | ||
this.code = code; | ||
} | ||
|
||
public UUID getId() { | ||
return id; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public String getCode() { | ||
return code; | ||
} | ||
|
||
public Set<M2MDepart> getDepartments() { | ||
return departments; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
M2MEmp employee = (M2MEmp) o; | ||
return Objects.equals(code, employee.code); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(code); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.tests.sets; | ||
|
||
import io.ebean.DB; | ||
import io.ebean.test.LoggedSql; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.List; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
class TestM2MSet { | ||
|
||
@Test | ||
void lazyLoadM2M_when_setWithHashCode_expect_selectProperties() { | ||
final M2MDepart department = new M2MDepart("Test"); | ||
final M2MEmp employee = new M2MEmp("Test", "Code"); | ||
DB.save(employee); | ||
department.addEmployee(employee); | ||
DB.save(department); | ||
|
||
LoggedSql.start(); | ||
DB.find(M2MDepart.class, department.getId()) | ||
.employees() | ||
.forEach(e -> assertThat(e.getName()).isNotNull()); | ||
|
||
List<String> sql = LoggedSql.stop(); | ||
assertThat(sql).hasSize(2); | ||
assertThat(sql.get(0)).contains("select t0.id, t0.name from m2_mdepart t0 where t0.id = ?"); | ||
assertThat(sql.get(1)).contains("select int_.m2_mdepart_id, t0.id, t0.code, t0.name from m2_memp t0 left join m2_mdepart_memp int_ on int_.m2_memp_id = t0.id where"); | ||
} | ||
} |