bdz
bdz

Reputation: 270

How to use embedded model properly with play framework?

I have an embedded model scheme. There is an Agent and the Agent has a City where the agent is located.

The models are looking the following:

City:

package models;

import java.util.*;
import javax.persistence.*;

import play.db.jpa.*;
import play.data.validation.*;

@Entity
public class City extends Model {
    @Required
    @Column(unique=true)
    public String name;

    @ElementCollection
    @CollectionTable(name="city_translation",
        joinColumns=@JoinColumn(name="city_id"))
    @Column(name="translation")
    @MapKeyColumn(name="language")
    public Map<String, String> translations = new HashMap<String, String>();

    public City(String name) {
        this.name = name;
    }

    public String toString() {
        return this.name;
    }

    public void setTranslation(String language, String translation) {
        translations.put(language, translation);
    }

    public String getTranslation(String language) {
        return translations.get(language);
    }
}

Agent:

package models;

import java.util.*;
import javax.persistence.*;

import play.db.jpa.*;
import play.data.validation.*;

@Entity
public class Agent extends Model {
    @Required
    @Column(unique=true)
    public String name;

    @Required
    @Column(unique=true)
    public String email;

    @Required
    public City city;

    public Agent(String name, String email, City city) {
        this.name = name;
        this.email = email;
        this.city = city;
    }
}

The problem is when the Agent model is created in the database (h2:mem) the city field is declared as varbinary(255) instead of bigint so it can not hold a City id.

Thus when in the controller I want to save an Agent the field is passed correctly (html: agent.city is the selected city id) and I can read it from params.get("agent.city") but when I want to reference it as agent.city it holds null:

public static save(Agent agent) {
    Logger.info(params.get("agent.id")); // OK - for example: 1
    if (agent.city == null)
        Logger.info("agent.city is null"); // this is printed
}

If I add the @Embeddable to the City class and add the @Embedded notation to the city property of the Agent then I have this error at compile time:

A JPA error occurred (Unable to build EntityManagerFactory): component property not found: id

Please advice how to set up the models correclty.

I'd avoid to use a OneToOne relationship with join table since then I'd need the reference id in the City model too, but the City model should be stay independent, it is used in other models too.

Thank you

Upvotes: 2

Views: 1369

Answers (1)

emt14
emt14

Reputation: 4896

Use @OneToOne on the City property of the Agent entity. You do not have to declare OneToOne in your city object. This means that the relationship will be unidirectional but still valid.

Upvotes: 1

Related Questions