How to persist one to one asociation?

Hello, I need to establish a one-to-one relationship between classes A and B. Where case A is the owner of the relation and when assigning from call B the value is lost. I leave you an example project.

Thank you

package com.company.sampleonetoone.entity;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.OneToOne;
import com.haulmont.cuba.core.entity.StandardEntity;

 @Table(name = "SAMPLEONETOONE_B")
 @Entity(name = "sampleonetoone$B")
public class B extends StandardEntity {
private static final long serialVersionUID = -6636144354361612238L;

@Column(name = "FIELD1")
protected String field1;

@OneToOne(fetch = FetchType.LAZY, mappedBy = "b")
protected A a;

public void setField1(String field1) {
    this.field1 = field1;
}

public String getField1() {
    return field1;
}

public void setA(A a) {
    this.a = a;
}

public A getA() {
    return a;
}

}

import javax.persistence.Entity;
 import javax.persistence.Table;
import javax.persistence.Column;
import com.haulmont.cuba.core.entity.StandardEntity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

 @Table(name = "SAMPLEONETOONE_A")
 @Entity(name = "sampleonetoone$A")
public class A extends StandardEntity {
private static final long serialVersionUID = -3492608347267339251L;

@Column(name = "FIELD1", nullable = false)
protected String field1;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "B_ID")
protected B b;

public void setB(B b) {
    this.b = b;
}

public B getB() {
    return b;
}


public void setField1(String field1) {
    this.field1 = field1;
}

public String getField1() {
    return field1;
}


}

an example

an example

As workaround i do the next

 package com.company.sampleonetoone.listener;

import com.company.sampleonetoone.entity.A;
import com.haulmont.cuba.core.Persistence;
import org.springframework.stereotype.Component;
import com.haulmont.cuba.core.listener.BeforeInsertEntityListener;
import com.haulmont.cuba.core.EntityManager;
import com.company.sampleonetoone.entity.B;
import com.haulmont.cuba.core.listener.BeforeUpdateEntityListener;
import com.haulmont.cuba.core.listener.AfterInsertEntityListener;
import java.sql.Connection;
import com.haulmont.cuba.core.listener.AfterUpdateEntityListener;

import javax.inject.Inject;
import com.haulmont.cuba.core.listener.BeforeDeleteEntityListener;

@Component("sampleonetoone_BListener")
public class BListener implements BeforeInsertEntityListener<B>, BeforeUpdateEntityListener<B>,   BeforeDeleteEntityListener<B> {



    @Inject
    protected Persistence persistence;

    @Override
    public void onBeforeInsert(B entity, EntityManager entityManager) {

        if(entity.getA()!=null){
          A a= entityManager.find(entity.getA().getClass(),entity.getA().getUuid());
          a.setB(entity);
          entityManager.persist(a);
        }
    }


    @Override
    public void onBeforeUpdate(B entity, EntityManager entityManager) {

       A aold= (A) persistence.getTools().getOldValue(entity, "a");
       if(aold!=null && (entity.getA()==null || aold.getUuid()!= entity.getA().getUuid())){
           aold.setB(null);
           entityManager.persist(aold);
       }
       if(entity.getA()!=null){
          A a= entityManager.find(A.class,entity.getA().getUuid());
          a.setB(entity);
          entityManager.persist(a);
       }
    }




    @Override
    public void onBeforeDelete(B entity, EntityManager entityManager) {
        A aold= entity.getA();
        if(aold!=null){
           aold.setB(null);
           entityManager.persist(aold);
        }



    }


}

JPA saves relations only from owning side. What about changing the model to make the needed side (or both sides) owning?

Thanks for your answer. My solution does not look elegant. But table A is large and I need the field of relation B to be in table A. Can an ONETOONE association have Both Owning Side? how can I do it?

Yes you can have both sides owning, i.e. having a foreign key column. The current version of Studio does not support it, but you can do it in the entity source code. Just remove the mappedBy attribute from the @OneToOne annotation and add the @JoinColumn annotation, for example:

@Table(name = "SAMPLE_BAR")
@Entity(name = "sample$Bar")
public class Bar extends StandardEntity {

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "FOO_ID")
    protected Foo foo;

After that Studio will generate correct database scripts including your manually defined FOO_ID column.