Slim3 Datastore‎ > ‎Relationships‎ > ‎

Bidirectional One-to-One Relationships

The following example defines a unidirectional one-to-one relationship:

@Model
public
class Employee {
   
@Attribute(primaryKey = true)
   
private Key key;

private ModelRef<Address> addressRef = new ModelRef<Address>(Address.class);

   
// ...
}

@Model
public
class Address {
   
@Attribute(primaryKey = true)
   
private Key key;

   
// ...
}

Let's add an inverse one-to-one relationship to Address.
To define it, use InverseModelRef<ModelType, OwnerType>.
@Model
public
class Address {
   
@Attribute(primaryKey = true)
   
private Key key;

private InverseModelRef<Employee, Address> employeeRef;

   
// ...
}

The following error will be shown for employeeRef field:
[SLIM3GEN1035] Specify @Attribute(persistent = false).
ModelRef has a key internally, so you need to persist it.
But this property is read only, so you do not need to persist it.

As the message says, define @Attribute(persistent = false) as follows:
@Model
public
class Address {
   
@Attribute(primaryKey = true)
   
private Key key;

@Attribute(persistent = false)
private InverseModelRef<Employee, Address> employeeRef;

   
// ...
}

The following error will be shown for employeeRef field:
[SLIM3GEN1011] The getter method is not found.

Use quick fix(hold down CTRL+1) and select "Create getter and setter for 'employeeRef'".
The following error will be shown for setEmployeeRef method:
[SLIM3GEN1039] The setter method for the field[employeeRef] is not allowed. Define the field as follows:
InverseModelRef<Employee, Address> employeeRef =
  new InverseModelRef<Employee, Address>(Employee.class ,"xxx", this);
The 'xxx' means the mapped ModelRef<Address> property name in the class[Employee].

In this case, 'xxx' is 'addressRef'.
As the message says, define employeeRef field and replace 'xxx' with 'addressRef'. If you do not use GWT, you can use EmployeeMeta.get().addressRef.getName() type-safely instead of "addressRef".
@Model
public
class Address {
   
@Attribute(primaryKey = true)
   
private Key key;

@Attribute(persistent = false)
private InverseModelRef<Employee,
Address> employeeRef =
new InverseModelRef<Employee,
Address>(Employee.class, "addressRef", this);

   
// ...
}


Then delete setEmployeeRef method.

Now let's create an employee and an address.
Address address = new Address();
...
Employee employee = new Employee();
...
employee.getAddressRef().setModel(address);
Datastore.put(address, employee);

You can get an address and an employee. The relationship is loaded lazily.
Key addressKey = ...;
Address address = Datastore.get(Address.class, addressKey);
Employee employee = address.getEmployeeRef().getModel();

Next...

Continue to Unidirectional Many-to-One Relationships.


Comments