Metadata.create returns same object twice?

I have a situation where metadata.create seems to be returning the same object more than once. Here is the code:

    @Subscribe("tblSchematicStateOmit.create")
    private void onTblSchematicStateOmitCreate(Action.ActionPerformedEvent event) {
        SchematicStateOmit stateOmit = metadata.create(SchematicStateOmit.class);
        stateOmit.setSchematic(getEditedEntity());
        stateOmitsDc.getMutableItems().add(dataContext.merge(stateOmit));
    }

When a user adds a row to the table, we create the appropriate object and add it to the Data Container after initializing a foreign key field.

I have pressed the button twice in my interface. Here is what the debugger shows as the value of the collection:

image

As you can see, the same object Id has been returned twice. Note that the entity has a composite key called SchematicstateomitsCompKey. The composite key has two fields:

    @Column(name = "SCHEMATICID", nullable = false)
    private Long schematicid;

    @Column(name = "STATEOMIT", nullable = false, length = 2)
    private String stateomit;

and in SchematicStateOmit object:

    @EmbeddedId
    private SchematicstateomitsCompKey id;

    @MapsId("schematicid")
    @JoinColumn(name = "SCHEMATICID")
    @ManyToOne(fetch = FetchType.LAZY)
    private Schematic schematic;

    public Schematic getSchematic() { return schematic; }

    public void setSchematic(Schematic schematic) {
        this.schematic = schematic;
        this.id.setSchematicid(schematic.getId());
    }

    @Override
    public SchematicstateomitsCompKey getId() {
        return id;
    }

    @Override
    public void setId(SchematicstateomitsCompKey id) {
        this.id = id;
    }

Is there a special way to create an entity with a composite key?

What else am I missing here?

As sometimes happens, I have managed to solve it myself. I am posting the modified code here. It may not all be necessary, but it does work:

    @Subscribe("tblSchematicStateOmit.create")
    private void onTblSchematicStateOmitCreate(Action.ActionPerformedEvent event) {
        SchematicstateomitsCompKey stateOmitKey = dataContext.create(SchematicstateomitsCompKey.class);
        stateOmitKey.setSchematicid(getEditedEntity().getId());
        SchematicStateOmit stateOmit = dataContext.create(SchematicStateOmit.class);
        stateOmit.setId(stateOmitKey);
        stateOmit.setSchematic(getEditedEntity());
        stateOmitsDc.getMutableItems().add(stateOmit);
    }

Changes are:

  1. Create a composite key object myself and use setId() to save it in the entity. (Is this necessary)?
  2. Use dataContext.create(), which is supposedly equivalent to dataContext.merge(metadata.create…)). I find that I don’t get duplicated entity Ids by doing this, where the previous code seemed to return the same object multiple times.

Hope somebody finds this useful.

Hi Eric,

I guess the issue is caused not by metadata.create() but by merging the instances to DataContext. When you perform dataContext.merge(), you get back another instance which was put into the context before if its id equals to your instance’s id. In your case, when you merge the second instance, you get back the first one, because their ids are equal.

To avoid this, try to set some value to an attribute of the id object before merging the instance. In fact, this is what you do in your second code fragment.

Thanks.