Ebean @ManyToOne, finder is not fetching all data of related object

I am using Ebean for my object mapping and I made SQL tables this way

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 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 the 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 next

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 company ID assigned to the employee), but the second shows null (which I expected should be "Microsoft"), with the result being

1
null

      

So the question is, why is only the company model ID being retrieved and not other related data?

+3


source to share


2 answers


  • You can use fetch () to eagerly fetch other parts of the graph. In this case, enter the name of the company, for example:

    Employee.find.fetch ("company", "name"), where () eq ("Identifier", 1) .findUnique (); ..

  • In the short field, the access cannot be intercepted (unless you activate the caller). Thus, using the accessor field for company.name meant that customer.name was a GETFIELD operation and that Ebean was not intercepted and therefore no lazy loading was invoked (and therefore null was returned).

Changing to using getters / setters meant that calling customer.getName () was lazy loading.

Java does not support properties (hance the getters and setters). You can look at other JVM languages ​​that are really similar to Groovy and Kotlin.



Groovy maintains properties, example using Groovy with @CompileStatic: 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, for example: https://github.com/ebean-orm/avaje-ebeanorm-examples/tree/master/e-kotlin-maven

Cheers, Rob.

+5


source


I ran into this problem today and I found out why it is not being called lazily when accessing a public variable.

The ribbon can be called lazily by calling the attributes method getter

. So I need to create getter

model selections in my data using the method getter

.

@Entity
public class Company extends Model
{
    @Id
    public Integer id;
    public String name;

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

      



Then select a company:

System.out.println(mrJohn.company.getName());

      

+1


source







All Articles