JPA cannot save a circular model

321 views
Skip to first unread message

Adrian Perreau de Pinninck

unread,
Oct 25, 2011, 3:24:09 AM10/25/11
to play-framework
Hi there,

I have a circular relation among models, when I try to save the main model
after having populated all the sub-models it throws the following exception:

A javax.persistence.PersistenceException has been caught,
org.hibernate.PropertyValueException: not-null property references a null or
transient value: models.PropertyValue.name
 
Yet the objects reference is not null, therefore it must be transient. I
believe that JPA saves one side of the model graph before the other and the
object to which PropertyValue.name refers to has not been save yet.

Since it is hard to explain I have attached the simplest version of that
which breaks to see if any of you good Samaritans can give me a hand.
Thanks a million


@Entity
public class MoleculeDatabase extends Model {

    @Column(nullable = false)
    public String name;
   
    @OneToMany(cascade = CascadeType.ALL)
    public List<Molecule> molecules;
   
    @OneToMany(cascade = CascadeType.ALL)
    public List<PropertyName> properties;


    public MoleculeDatabase() {
        super();
        this.molecules = new ArrayList<Molecule>();
        this.properties = new ArrayList<PropertyName>();
    }
   
}

@Entity
public class Molecule extends Model {

    @Column(nullable = false)
    public String name;

    @ManyToOne(optional = true, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    public MoleculeDatabase database;

    @OneToMany(cascade = CascadeType.ALL)
    public List<Deployment> deployments;

    public Molecule() {
        super();
        deployments = new ArrayList<Deployment>();
    }
   
}

@Entity
public class Deployment extends Model {

    @Column(nullable = false)
    public String name;
   
    @ManyToOne(optional = false)
    public Molecule molecule;
   
    @OneToMany(cascade = CascadeType.ALL)
    public List<PropertyValue> properties;
   
    public Deployment() {
        super();
        this.properties = new ArrayList<PropertyValue>();
    }

}

@Entity
public class PropertyName extends Model {
   
    @Column(nullable = false)
    public String name;
   
    @ManyToOne(optional = false)
    public MoleculeDatabase database;

}

@Entity
public class PropertyValue extends Model {
   
    @ManyToOne(optional = false)
    public PropertyName name;
   
    @Column(nullable = false)
    public String value;
   
    @ManyToOne(optional = false)
    public Deployment deployment;

}

public class MoleculeDatabaseTest extends UnitTest {

    MoleculeDatabase db;
    Deployment deployment;
   
    @Before
    public void setup(){
        db = new MoleculeDatabase();
        db.name = "SomeName";

        deployment = new Deployment();
        deployment.name = "testName_mol12";

        Molecule molecule = new Molecule();
        molecule.name = "testName_mol12";
        molecule.deployments.add(deployment);
        deployment.molecule = molecule;

        db.molecules.add(molecule);
        molecule.database = db;
    }
   
    @Test
    public void databaseWithPropertiesIsSavedCorrectly(){

        PropertyName propertyName = new PropertyName();
        propertyName.database = db;
        propertyName.name = "COMPND";
        db.properties.add(propertyName);
       
        PropertyValue propertyValue = new PropertyValue();
        propertyValue.value = "testName_mol12";
        propertyValue.name = propertyName;
        propertyValue.deployment = deployment;
       
        deployment.properties.add(propertyValue);
   
        assertEquals(db.properties.get(0), deployment.properties.get(0).name);
        db.save();
    }

}

--
Adrián Perreau de Pinninck Bas, Ph.D
Twitter: @eidrien

Josh Kamau

unread,
Oct 25, 2011, 3:36:18 AM10/25/11
to play-fr...@googlegroups.com

For bi-directional relationships, you need to put 'mappedBy' on one side.


Josh.

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.

Reply all
Reply to author
Forward
0 new messages