Skip to main content

[SOLVED] JPA settings problem

5 replies [Last post]
cleitonls
Offline
Joined: 2005-05-20

Hi All,

I've had problem to map a composite key between a Customer class and Phone class in EJB3.

I mapped these classes like shown below and working fine without using EJB3. Therefore when I use these entities in EJB3 and try to retrieve a Customer, the aplication keep a loop until Glassfish turn off through protocol violation.

<br />
@Entity<br />
@Table( name="CFGCUSTOM" )<br />
@javax.persistence.SequenceGenerator(<br />
    name="SEQ_CUSTOM",<br />
    sequenceName="SEQ_CUSTO" )<br />
public class Customer extends VObject {<br />
    @Id<br />
    @Column( name="NIDCUST" )<br />
    @GeneratedValue( strategy=GenerationType.SEQUENCE, generator="SEQ_CUSTO" )<br />
    private Long id;</p>
<p>    @NotNull<br />
    @Column( name="CNAMECUST")<br />
    private String name;</p>
<p>    @OneToMany( mappedBy="id.customer", cascade = { CascadeType.ALL }, fetch=FetchType.EAGER )<br />
    private Set phones= new HashSet();<br />
    ....<br />
    ....<br />
    ....<br />
}<br />

<br />
@Entity<br />
@Table( name="CFGPHONE" )<br />
@AssociationOverride( name="id.customer", joinColumns = { @JoinColumn( name="NIDCUST" ) } )<br />
public class Phone extends VObject {<br />
    @EmbeddedId private PhonePk id;</p>
<p>    @NotNull<br />
    @Column( name="CFGNPHONE" )<br />
    private String number</p>
<p>    @NotNull<br />
    @Column( name="CTYPEPHONE" )<br />
    private String phoneType;<br />
    ....<br />
    ....<br />
    ....<br />
}<br />

<br />
@Embeddable<br />
public class PhonePk implements Serializable {<br />
    @Column( name="NIDPHONE" )<br />
    private Long id;</p>
<p>    @ManyToOne( fetch=FetchType.EAGER )<br />
    @JoinColumn( name="NIDCUST" )<br />
    private Customer customer;<br />
    ....<br />
    ....<br />
    ....<br />
}<br />

I read these mappings aren't support in EJB3, but I'm not sure. Do anybody know how to solve it.

Thanks,
Cleiton

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mf125085
Offline
Joined: 2005-03-29

Is it possible to move the relationship field from the embedded cllass PhonePk to Phone? As you have a NIDPHONE column (which seems to be unique) in the PHONE table, do you need the embeddable PhonePk class at all?

cleitonls
Offline
Joined: 2005-05-20

Hi mf125085,

Thanks for your reply!

So, I need a composite pk in Phone class where this pk MUST be composed by id from Costumer and sequencer id like shown in PhonePk class.

I need a composite key in EJB3. If there is a way to do it without an embeddable class, it's ok.

Only to remember! Like I said latter this mapping work fine when I use without EJB3.

Regards,
Cleiton

mf125085
Offline
Joined: 2005-03-29

You should definitely move the relationship into the Phone class.

For an example on composite keys, check out the classes LineItem and LineItemKey in the Javaee 5 tutorial:

http://java.sun.com/javaee/5/docs/tutorial/doc.

The classes can be found under

examples/ejb/order/order-ejb/src/java/order/entity

IMHO, PhonePk should only have the fields [i]number[/i] and [i]phoneType[/i].

cleitonls
Offline
Joined: 2005-05-20

Hi mf125085,

I got to do as you advised and work fine, Therefore I didn't put number and phoneType in PhonePK but in Phone.

Follow the final code:

[code]
@Entity
@Table( name="CFGCUSTOM" )
@javax.persistence.SequenceGenerator(
name="SEQ_CUSTOM",
sequenceName="SEQ_CUSTO" )
public class Customer extends VObject {
@Id
@Column( name="NIDCUST" )
@GeneratedValue( strategy=GenerationType.SEQUENCE, generator="SEQ_CUSTO" )
private Long id;

@NotNull
@Column( name="CNAMECUST")
private String name;

@OneToMany(fetch=FetchType.EAGER, mappedBy = "customer")
private Set phones = new HashSet();
....
....
....
}
[/code]

[code]
@Entity
@Table( name="CFGPHONE" )
@IdClass(PhonePk.class)
public class Phone extends VObject {
@Id
@Column(name="NIDPHONE", nullable = false)
private Long id;

@Id
@Column(name="NIDCUST", nullable = false, insertable = false, updatable = false)
private Long idCustomer;

@NotNull
@Column( name="CFGNPHONE" )
private String number

@NotNull
@Column( name="CTYPEPHONE" )
private String phoneType;

@ManyToOne
@JoinColumn(name = "NIDCUST", referencedColumnName = "NIDCUST")
private Customer customer;
....
....
....
}
[/code]

[code]
public class PhonePk implements Serializable {
@Column( name="NIDPHONE" )
private Long id;

@Column(name="NIDCUST")
private Customer idCustomer;
....
....
....
}
[/code]

Best regards,
Cleiton

mf125085
Offline
Joined: 2005-03-29

Hi Cleiton,

Great, that you got it working!

As the relationship customer in Phone is mapped to a primary key column, it's defined when a phone instance is created, and can not be changed. Therefore, the customer field should be mapped read only, i.e.:

@Entity
@Table( name="CFGPHONE" )
@IdClass(PhonePk.class)
public class Phone extends VObject {
@Id
@Column(name="NIDPHONE", nullable = false)
private Long id;

@Id
@Column(name="NIDCUST", nullable = false)
private Long idCustomer;

@NotNull
@Column( name="CFGNPHONE" )
private String number

@NotNull
@Column( name="CTYPEPHONE" )
private String phoneType;

@ManyToOne
@JoinColumn(name = "NIDCUST", referencedColumnName = "NIDCUST", insertable = false, updatable = false)
private Customer customer;
....
....
....
}