Documentation

YAML

YAML syntax

Your application tests will often use data structures that consist of related model objects, which can be tedious to create programmatically in Java. Play includes a YAML parser which makes the task much simpler.

Create a YAML file like the following, in the conf directory.

City(capitalfederal):
    name: Capital Federal
    state: Buenos Aires

User(john):
    name: "John Smith"
    email: john@john.com
    lang: es
    created: 2007-01-01

User(frank):
    name: "Frank Franken"
    email: frank@frank.com
    lang: en
    created: 2007-08-05

Neighborhood(villalugano):
    name: Villa Lugano
    city: capitalfederal
    tags: "shopping, cafes"
    users: [john, frank]

Neighborhood(coghlan):
    name: Coghlan
    city: capitalfederal
    tags: "cafes, bars"
    users: [john]

Play’s YAML syntax varies slightly from the standard. Each stanza must start with the name of the model class (eg Neighborhood) and be followed by an identifier in brackets (eg villalugano), which you can use to reference the object elsewhere in the file. This is different to standard YAML syntax, which uses the ampersand character to indicate a reference.

Play uses SnakeYAML, which has an excellent documentation page with many examples.

Model classes

The YAML file can contain one-to-many, many-to-one and many-to-many relationships. These relationships must be explicity annotated in the model classes, and you must indicate which is the “owning side” of the relationship.

City.java

package models;

import java.util.List;
import javax.persistence.*;
import play.db.jpa.Model;

@Entity
public class City extends Model {
    public String name;
    public String state;
    
    // bi-directional one-to-many, inverse side
    @OneToMany(mappedBy = "city", cascade = CascadeType.ALL)
    public List<Neighborhood> neighborhoods;
}

Neighborhood.java

package models;

import java.util.List;
import javax.persistence.*;
import play.db.jpa.Model;

@Entity
public class Neighborhood extends Model {
    public String name;
    
    // bi-directional one-to-many, owning side
    @ManyToOne
    public City city;
    
    public String tags;
    
    // owning side
    @ManyToMany
    public List<User> users;
}

User.java

package models;

import java.util.*;
import javax.persistence.*;
import play.db.jpa.Model;

@Entity
//@Table(name = "`user`")
public class User extends Model {
    public String name;
    public String email;
    public String lang;
    public Date created;
    
    // inverse side of the relation
    @ManyToMany(mappedBy = "users")
    public List<Neighborhood> neighborhoods;
}


Note that if you are using PostgreSQL you may need to explicitly set the name of the user table with escape characters because user is a reserved word.

Loading the data structure in your application

Typically you will load the data structure defined in the YAML file as part of a unit test. But sometimes you may wish to populate the database with specific data in other circumstances, for example when your application starts for the first time.

import play.*;
import play.jobs.*;
import play.test.*;
import models.*;

@OnApplicationStart
public class Bootstrap extends Job {
    public void doJob() {
        // Check if the database is empty
        if(User.count() == 0) {
            Fixtures.loadModels("initial-data.yml");
        }
    }
}

The objects will be created in the database, and you can then access them as you would any other model object.

City city = City.all().first();
List<Neighborhood> neighborhoods = city.neighborhoods;