NullPointerException with Join Table Entity

49 views
Skip to first unread message

kraythe

unread,
Oct 13, 2016, 1:55:29 PM10/13/16
to Ebean ORM
I have a problem with a join table entity. The code is shown below but understand that this has been changed to remove irrelevant details and hide proprietary information. However, the problem is the same. In this case when an employee is loaded that is not associated with a department then a NullPointerException is thrown when setting the field for the Embedded Key. Can someone tell me what I am doing wrong, if anything, and how I can fix or work around the problem. 

Caused by: java.lang.NullPointerException: null
   at models.contest.BetSlipXContestKey._ebean_setField(EmployeeXDepartmentKey.java:1)
   at com.avaje.ebeaninternal.server.properties.EnhanceBeanPropertyInfo$Setter.set(EnhanceBeanPropertyInfo.java:84)
   at com.avaje.ebeaninternal.server.deploy.BeanProperty.setValue(BeanProperty.java:691)

@Entity
@Table(name = "employee")
public class Employee implements Serializable {
   
private static final long serialVersionUID = 1L;

   
@SuppressWarnings("unused")
   
@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
   
@Column(name = "id")
   
private long id;

   
@Column(name = "uuid", nullable = false)
   
private String uuid;

   
@SuppressWarnings({"UnusedDeclaration"})
   
@OneToMany(mappedBy = "betSlip", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   
@PrivateOwned
   
private List<EmployeeXDepartment> departments;

   
public Employee(final Collection<Department> departments) {
       
this.uuid = UUID.randomUUID().toString();
       
this.departments = departments.stream()
               
.map(d -> new EmployeeXDepartment(this, d.getId()))
               
.collect(toList());
   
}

   
public long getId() {
       
return id;
   
}

   
public String getUuid() {
       
return uuid;
   
}

   
private void setDepartments(List<EmployeeXDepartment> departments) {
       
this.departments = departments;
   
}

   
public List<EmployeeXDepartment> getDepartments() {
       
return departments;
   
}
}

@Entity
@Table(name = "employee_x_department")
public class EmployeeXDepartment implements Serializable {
   
private static final long serialVersionUID = 1L;
   
@EmbeddedId
    private EmployeeXDepartmentKey key;

   
@ManyToOne
    @JoinColumn(name = "employee_id", referencedColumnName = "id", insertable = false, updatable = false)
   
private Employee employee;

   
public EmployeeXDepartment(final Employee employee, final int contestId) {
       
this.key = new EmployeeXDepartmentKey(employee.getId(), contestId);
       
this.employee = employee;
   
}

   
public Employee getEmployee() {
       
return employee;
   
}

   
public void setEmployee(final Employee employee) {
       
this.key.setEmployeeId(employee.getId());
       
this.employee = employee;
   
}

   
public int getContestId() {
       
return key.getDepartmentId();
   
}

   
public void setContestId(final int contestId) {
       
this.key.setDepartmentId(contestId);
   
}

   
@SuppressWarnings("unused") // Used by Ebeans
    @PrePersist
    public void prePersist() throws IOException {
       
key.setEmployeeId(employee.getId());
   
}
}

@Embeddable
public class EmployeeXDepartmentKey implements Serializable {
   
private static final long serialVersionUID = 1L;
   
@ManyToOne
    @Column(name = "employee_id", nullable = false)
   
private long employeeId;
   
@Column(name = "department_id", nullable = false)
   
private int departmentId;

   
public EmployeeXDepartmentKey(final long employeeId, final int departmentId) {
       
this.employeeId = employeeId;
       
this.departmentId = departmentId;
   
}

   
public int getDepartmentId() {
       
return departmentId;
   
}

   
public void setDepartmentId(final int departmentId) {
       
this.departmentId = departmentId;
   
}

   
public long getEmployeeId() {
       
return employeeId;
   
}

   
public void setEmployeeId(final long employeeId) {
       
this.employeeId = employeeId;
   
}

   
@Override
    public boolean equals(final Object o) {
       
if (this == o) return true;
       
if (o == null || getClass() != o.getClass()) return false;
       
final EmployeeXDepartmentKey that = (EmployeeXDepartmentKey) o;
       
return employeeId == that.employeeId &&
               
departmentId == that.departmentId;
   
}

   
@Override
    public int hashCode() {
       
return Objects.hash(employeeId, departmentId);
   
}
}


kraythe

unread,
Oct 13, 2016, 2:42:17 PM10/13/16
to Ebean ORM
Bah I left contest id in rather than department id. I guess my sanitation didnt work but you get the idea I hope. It does have to do with contests. :) 

Rob Bygrave

unread,
Oct 14, 2016, 1:59:11 AM10/14/16
to ebean@googlegroups

It is not clear to me if you still have a NPE ?  If so can you include the full stack trace and the code you run to reproduce the issue.

Thanks, Rob.


--

---
You received this message because you are subscribed to the Google Groups "Ebean ORM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ebean+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

kraythe

unread,
Oct 17, 2016, 11:30:15 AM10/17/16
to Ebean ORM
Well the version I passed is basically what the code was that was run. Obviously my sanitation of the code for NDA reasons is hit and miss. The problem is that Ebeans is trying to set the primitive field to null. This happens when there are no departments for an employee above. The rest of the stack is standard Ebeans. I have pasted a sanitized version below. 

2016-10-17 15:17:00 +0000 - [ERROR] - [MapCacheImpl] (models.contest.BetSlip): Exception Thrown while refreshing
java
.util.concurrent.CompletionException: javax.persistence.PersistenceException: Error readSet on models.EmployeeXDepartmentKey.employeeId
   at java
.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
   at java
.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
   at java
.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1629)
   at java
.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1618)
   at java
.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
   at java
.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
   at java
.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
   at java
.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: javax.persistence.PersistenceException: Error readSet on models.EmployeeXDepartmentKey.employeeId
   at com
.avaje.ebeaninternal.server.deploy.BeanProperty.readSet(BeanProperty.java:604)
   at com
.avaje.ebeaninternal.server.deploy.id.IdBinderEmbedded.read(IdBinderEmbedded.java:314)
   at com
.avaje.ebeaninternal.server.deploy.id.IdBinderEmbedded.readSet(IdBinderEmbedded.java:329)
   at com
.avaje.ebeaninternal.server.query.SqlTreeNodeBean.load(SqlTreeNodeBean.java:238)
   at com
.avaje.ebeaninternal.server.query.SqlTreeNodeManyRoot.load(SqlTreeNodeManyRoot.java:25)
   at com
.avaje.ebeaninternal.server.query.SqlTreeNodeBean.load(SqlTreeNodeBean.java:298)
   at com
.avaje.ebeaninternal.server.query.CQuery.checkForDifferentBean(CQuery.java:469)
   at com
.avaje.ebeaninternal.server.query.CQuery.readNextBean(CQuery.java:447)
   at com
.avaje.ebeaninternal.server.query.CQuery.hasNext(CQuery.java:516)
   at com
.avaje.ebeaninternal.server.query.CQuery.readCollection(CQuery.java:547)
   at com
.avaje.ebeaninternal.server.query.CQueryEngine.findMany(CQueryEngine.java:330)
   at com
.avaje.ebeaninternal.server.query.DefaultOrmQueryEngine.findMany(DefaultOrmQueryEngine.java:105)
   at com
.avaje.ebeaninternal.server.core.OrmQueryRequest.findList(OrmQueryRequest.java:344)
   at com
.avaje.ebeaninternal.server.core.DefaultServer.findList(DefaultServer.java:1372)
   at com
.avaje.ebeaninternal.server.querydefn.DefaultOrmQuery.findList(DefaultOrmQuery.java:1141)
   at utils
.caching.EbeanCacheDataProvider.lambda$findIndexed$1(EbeanCacheDataProvider.java:122)
   at java
.lang.Iterable.forEach(Iterable.java:75)
   at utils
.caching.EbeanCacheDataProvider.findIndexed(EbeanCacheDataProvider.java:120)
   at utils
.caching.MapCacheImpl.lambda$loadCacheMisses$10(MapCacheImpl.java:457)
   at java
.lang.Iterable.forEach(Iterable.java:75)
   at utils
.caching.MapCacheImpl.loadCacheMisses(MapCacheImpl.java:455)
   at utils
.caching.MapCacheImpl.lambda$null$3(MapCacheImpl.java:222)
   at java
.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1626)
   
... 5 common frames omitted
Caused by: java.lang.RuntimeException: set employeeId on [models.EmployeeXDepartmentKey] arg[null] type[models.EmployeeXDepartmentKey] threw error
   at com
.avaje.ebeaninternal.server.deploy.BeanProperty.setValue(BeanProperty.java:693)
   at com
.avaje.ebeaninternal.server.deploy.BeanProperty.readSet(BeanProperty.java:600)

Thanks for your time!
To unsubscribe from this group and stop receiving emails from it, send an email to ebean+un...@googlegroups.com.

Rob Bygrave

unread,
Oct 17, 2016, 5:03:31 PM10/17/16
to ebean@googlegroups
In the above stack trace I think you have omitted the underlying exception / caused by.  Can you include that?
BeanProperty.java:693

Thanks, Rob.

To unsubscribe from this group and stop receiving emails from it, send an email to ebean+unsubscribe@googlegroups.com.

kraythe

unread,
Oct 18, 2016, 12:43:28 PM10/18/16
to Ebean ORM
Actually that is all there is to the stack trace. We get nothing more than that. :(
Reply all
Reply to author
Forward
0 new messages