I'm using Ebean for my object-mapping and I've made my SQL tables like so
create table company (
id int auto_increment not null primary key,
name varchar(100)
);
create table employee (
id int auto_increment not null primary key,
name varchar(100) not null,
company_id int not null,
constraint foreign key (company_id) references company (id)
on delete restrict on update restrict
);
This is the company Ebean model
import javax.persistence.Entity;
import javax.persistence.Id;
import com.avaje.ebean.Model;
@Entity
public class Company extends Model
{
@Id
public Integer id;
public String name;
}
And employee model
@Entity
public class Employee extends Model
{
@Id
public Integer id;
public String name;
@ManyToOne
public Company company;
public static Finder<Long, Employee> find = new Finder<Long, Employee>(Long.class, Employee.class);
}
When I run the following
Company company = new Company();
company.name = "Microsoft";
company.save();
Employee employee = new Employee();
employee.name = "Mr John";
employee.company = company;
employee.save();
Employee mrJohn = Employee.find.where().eq("id", 1).findUnique();
System.out.println(mrJohn.company.id);
System.out.println(mrJohn.company.name);
The first System.out.println gives 1 (which is the correct id of the company assigned to the employee) but the second shows null (which I expected should have the value "Microsoft"), the output being
1
null
The question therefore is why is only the id of the Company model retrieved, and not the other associated data?
You can use fetch() to eagerly fetch other parts of the graph. In this case fetch the company name like:
Employee.find.fetch("company","name").where().eq("id",1).findUnique();
In short field access can not be intercepted (unless you enhance the caller). So using field access for company.name meant that customer.name was a GETFIELD operation and that it was not being intercepted by Ebean and hence lazy loading was not invoked (and hence a null was returned).
Changing over to use getters/setters meant that lazy loading was invoked when customer.getName() was called.
Java does not support properties (hance the getters and setters). You can look at other JVM languages that do like Groovy and Kotlin.
Groovy supports properties, an example using Groovy with @CompileStatic is: https://github.com/ebean-orm/avaje-ebeanorm-examples/blob/master/e-groovy https://github.com/ebean-orm/avaje-ebeanorm-examples/blob/master/e-groovy/src/main/groovy/org/example/domain/Customer.groovy
Kotlin supports properties, an example is: https://github.com/ebean-orm/avaje-ebeanorm-examples/tree/master/e-kotlin-maven
Cheers, Rob.