Malexandre
Malexandre

Reputation: 215

Many-to-one unidirectional relation in DataNucleus

For the context, client-side I use the MVP pattern, so the view with the One list knows only the ID, and when my new Many is received on the server, I want to be able to just update the One's foreign key, with a "setOneId" or an empty One object with an ID set to the wanted value.

So I try to create a many-to-one unidirectional in DataNucleus, and I'm struggling a bit. I'm ok to use JDO or JPA, I don't really care. In JPA, I tried this :

@Entity
public class Many {
    @Id
    String id;

    @ManyToOne
    @Join(name = "idOne")
    One one;
}

@Entity
public class One {
    @Id
    String id;
}

It's almost what I want. The one-to-many is created but with a join table. I want to have a direct relation. And when I insert/update a Many, I don't want to insert/update the related One, just update the idOne with the good id in my Many object.

I found this blogpost, but it's with Hibernate, and I think it still use a join table :

@Entity
public class Many {
    @Id
    public String id;

    @Column(name="idOne")
    private String idOne;

    @ManyToOne
    @JoinColumn(name="idOne", nullable=false, insertable=false, updatable=false)
    private One one;
}

I tried it, but I got exactly this error.

I don't understand how I am struggling with that. My goal is to have a table that keep some reference data (like a list of country as the class One), and a list of "working item" (like a town as the class Many) that I create/update without create/update the reference data, just its foreign key in the Many object.

Upvotes: 0

Views: 1245

Answers (2)

DataNucleus
DataNucleus

Reputation: 15577

@Entity
public class A {
    @Id
    String id;

    @OneToOne(cascade=CascadeType.ALL)
    B b;
}

@Entity
public class B {
    @Id
    String id;
}

and then if you persisted initial objects as

tx.begin();
A a = new A("FirstA");
B b1 = new B("FirstB");
B b2 = new B("SecondB");
a.setB(b1);
em.persist(a);
em.persist(b2);
tx.commit();

... (some time later)
tx.begin();
A a = em.find(A.class, "FirstA");
B b2 = em.getReference(B.class, "SecondB");

// update the B in A to the second one
a.setB(b2);
tx.commit();

This updates the FK between A and B. Can't get simpler

Upvotes: 1

JustDanyul
JustDanyul

Reputation: 14044

If its a unidirectional association, and Many is the owning side (as per your second example), you are heading in the wrong direction. It doesn't make much sense to delegate the update and insert responsibility on the owning side of a unidirectional relationship (as done with the insertable=false and updateable=false).

EDIT: updated answer So what you want is a many-to-one, with a foreign key column on the owning side. Try this

@Entity
public class Many {
    @Id
    String id;

    @ManyToOne
    @JoinColumn(name = "foreignKeyColumn")
    One one;
}

Upvotes: 1

Related Questions