Shared primary key

128 views
Skip to first unread message

Dennis

unread,
May 30, 2012, 7:18:24 PM5/30/12
to eb...@googlegroups.com
Hello!

I have Good and StockStatus (of that good - sold, booked etc). Classes are something like 
class Good {
    @Id
    private long id;

    private StockStatus stockStatus;
    ...
}

class StockStatus {    
    private Good good;
    ...
}

StockStatus doesn't have primary key but it has reference to good. It can be considered as primary key.
So StockStatus has the same primary key as Good.
Can I map OneToOne relation from Good to StockStatus in EBean and how?

Thanks in advance.

Dennis.

Rob Bygrave

unread,
May 31, 2012, 4:44:43 PM5/31/12
to eb...@googlegroups.com
I think it would be good for you to explain what your database table design is.

Dennis

unread,
Jun 3, 2012, 8:05:43 AM6/3/12
to eb...@googlegroups.com
Sure.

select * from good;
+----+-------+----------------+--------+---------+--------+--------+--------+
| id | sku   | name           | serial | version | price1 | price2 | price3 |
+----+-------+----------------+--------+---------+--------+--------+--------+
| 67 | GOOD1 | Sample good 1  | t      |       2 | NULL   | NULL   | NULL   |
| 28 | GOOD2 | Sample good 2  | f      |       2 | NULL   | NULL   | NULL   |
+----+-------+----------------+--------+---------+--------+--------+--------+

select * from stock; (actually it's report view)
+------+-----------------+--------------+-------------------+----------------+
| good | stock_available | stock_booked | transit_available | transit_booked |
+------+-----------------+--------------+-------------------+----------------+
|   67 |               4 |           50 |                 0 |              0 |
|   28 |               1 |            5 |                 0 |              0 |
+------+-----------------+--------------+-------------------+----------------+

I want to map the following one-to-one relation:
@Entity
class Stock {
    private BigDecimal stockAvailable;
    ...
}

@Entity
class Good {
    @Id
    long id;
    Stock stock;
    ...
}

Rob Bygrave

unread,
Jun 4, 2012, 1:32:06 AM6/4/12
to eb...@googlegroups.com

So typically a OneToOne has it's own PK and a FK back to the related object. So typically it is the same as a OneToMany in terms of PK and FK but with an additional unique constraint to restrict the cardinality. This is different from this case.

So for this example Stock does not have a @Id specified. Assuming that Stock is effectively read only then I think you should define it's @Id to be 'good' and it's FK would also be 'good' - so it's PK and FK are mapped to the same column.

That should work.

Alternatively you could use @Formula properties on Good.

Cheers, Rob.

Dennis Setevoy

unread,
Jun 4, 2012, 5:58:39 AM6/4/12
to eb...@googlegroups.com

So typically a OneToOne has it's own PK and a FK back to the related object. So typically it is the same as a OneToMany in terms of PK and FK but with an additional unique constraint to restrict the cardinality.

Exactly. 

This is different from this case.

So for this example Stock does not have a @Id specified. Assuming that Stock is effectively read only then I think you should define it's @Id to be 'good' and it's FK would also be 'good' - so it's PK and FK are mapped to the same column.

That should work.

So am I understanding correctly that you suggest to map this as OneToMany?

Rob Bygrave

unread,
Jun 4, 2012, 6:15:02 AM6/4/12
to eb...@googlegroups.com
>> So am I understanding correctly that you suggest to map this as OneToMany?

No.  You need to define an @Id property to Stock - map that to the 'good' column which is also the same column as what the Good good; property is mapped to. That is, the primary key is also a foreign key.

I didn't see a @Id property on your Stock entity originally, so I'm saying you should add one (and map that to the 'good' column of the view).

Post your model objects up again in full if that is not clear or correct.

Cheers, Rob.

Dennis

unread,
Jun 4, 2012, 8:10:42 AM6/4/12
to eb...@googlegroups.com
Yes, StockLine is readOnly and no problem to annotate "good" with @Id. I even tried to do so.
But how should I annotate private StockLine stockline; from Good side?

Here are actual mappings.

@Entity
@Table(name = "good")
public class Good extends NamedEntity implements Versioned {
    // Following id is inherited from ancestor:
    // @Id
    // @Column(name="id")
    // private Long id;

    // Now I set it manually from seperate query so It's not annotated at all. But I want Ebean to join it for me in same query.
    private StockLine stockState;
    
    ...
}

@Entity
@Table(name = "stock")
public class StockLine {
    // There is no @Id here but no problem to add.
    @ManyToOne
    @JoinColumn(name="good", nullable = false)
    private Good good;

   ...
}

Rob Bygrave

unread,
Jun 4, 2012, 5:10:19 PM6/4/12
to eb...@googlegroups.com
You should use @OneToOne on both sides.  Sorry, the bit earlier about OneToMany probably was more confusing than helpful.

I think it should be something like:


public class Good
...
@OneToOne(mappedBy="good")
private StockLine stockState;



public class StockLine
...
@Id
@Column(name="good")
private Long id;

@OneToOne

@JoinColumn(name="good", nullable = false)
private Good good;



Dennis

unread,
Jul 2, 2012, 3:45:46 PM7/2/12
to eb...@googlegroups.com
Now it works as expected!
Thank you.

вторник, 5 июня 2012 г., 0:10:19 UTC+3 пользователь Rob Bygrave написал:
You should use @OneToOne on both sides.  Sorry, the bit earlier about OneToMany probably was more confusing than helpful.

I think it should be something like:


public class Good
...
@OneToOne(mappedBy="good")
private StockLine stockState;



public class StockLine
...
@Id
@Column(name="good")
private Long id;

@OneToOne
@JoinColumn(name="good", nullable = false)
private Good good;


Dennis. 
Reply all
Reply to author
Forward
0 new messages