Ebean EmbeddedId mapping column to ManyToOne relat

2019-02-19 16:33发布

问题:

I'm facing a problem with Ebean when trying to create Composed Keys (EmbeddedId).

This is a draft of what I have:

@Entity public class EntityA extends Model{
    @Id
    private String ID;

    @OneToMany
    private List<EntityB> listEntitesB; 

    public EntityA(){
        ID = UUID.randomUUID();
    }
}

@Entity public class EntityB extends Model{

    @EmbeddedId
    private EntityB_PK ID;

    @ManyToOne
    @JoinColumn(name="entityA_fk", referencedColumnName="listEntitiesB")
    private EntityA entityA; 

    public EntityB(String entityB_ID){
         ID = new EntityB_PK(UUID.randomUUID(), entityB_ID);
    }
}

@Embeddable public class EntityB_PK{
    private String entityB_ID;
    private String entityA_FK_ID;

    public EntityB_PK(String entB_ID, String entA_FK_ID){
       entityB_ID = entB_ID;
       entityA_FK_ID = entA_FK_ID;
    } 
}

Note: I'm using Ebean 4.1.4 with Java 1.6.

So, this code works well, but there is a perk, which I'm trying to solve - the resultant table in the database looks like this:

  • entityB_ID [primary]
  • entityA_FK_ID [primary]
  • entityA_fk

As you can see that last column is redundant considering the "entityA_FK_ID" column.

What I would like to have?

  • I would like to be able to tell Ebean to use the column "entityA_FK_ID" for the association @ManyToOne instead of creating it's own column.

回答1:

To solve this problem we have to:

  1. Map EntityB.entityA to the same column as EntityB.ID.entityA_FK_ID
  2. set 'insertable' and 'updateable' attributes of EntityB.entityA @JoinColumn annotation
  3. Override setter of EntityB.entityA

Here is the code:

EntityA.java:

@Entity 
public class EntityA extends Model {
    @Id
    private String ID;

    @OneToMany(mappedBy="entityA")
    public List<EntityB> listEntitesB; 

    public static Finder<String,EntityA> find = new Finder<String,EntityA>(
        String.class, EntityA.class
    ); 

    public EntityA() {
        ID = UUID.randomUUID().toString();
    }

    public String getID() {
        return ID;
    }
}

EntityB.java:

@Entity 
public class EntityB extends Model {

    @EmbeddedId
    private EntityB_PK ID;

    @ManyToOne
    @JoinColumn(name = "entityA_fk_id", insertable = false, updatable = false)
    private EntityA entityA; 

    public EntityA getEntityA() {
        return entityA;
    }

    public void setEntityA(EntityA aEntityA) {
        entityA = aEntityA;
        ID.entityA_FK_ID = aEntityA.getID();
    }

    public EntityB(String entityB_ID){
         ID = new EntityB_PK(UUID.randomUUID().toString(), entityB_ID);
    }

    public String getID() {
        return ID.entityB_ID;
    }
}

EntityB_PK.java:

@Embeddable 
public class EntityB_PK implements Serializable {

    public String entityB_ID;

    @Column(name="entityA_fk_id")
    public String entityA_FK_ID;

    public EntityB_PK(String entB_ID, String entA_FK_ID){
       entityB_ID = entB_ID;
       entityA_FK_ID = entA_FK_ID;
    } 

    @Override
    public int hashCode() {
        return entityB_ID.length() + entityA_FK_ID.length();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) 
            return true;
        EntityB_PK b = (EntityB_PK)obj;
        if(b==null)
            return false;
        if (b.entityB_ID.equals(entityB_ID) && b.entityA_FK_ID.equals(entityA_FK_ID)) {
            return true;
        }
        return false;
    }
}