Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Need advice on setup Phone ManyToOne JoinColumns Employee Relationship(Syntax error "@JoinColumns.value is not an annotation type" )
Need advice on setup Phone ManyToOne JoinColumns Employee Relationship [message #1085125] Mon, 12 August 2013 09:38 Go to next message
George Jackson is currently offline George Jackson
Messages: 6
Registered: March 2013
Junior Member
Razz Dear EclipseLink Specialists,

I am at a lost on why the syntax error "@JoinColumns.value is not an annotation type" from a hypothetical OneToMany Composite key relational mapping between Employee & Phone entities example as follows:

@Entity

@IdClass(EmployeePK.class)
@Table(name="EMPLOYEE", catalog="CorporationDB", schema="")
public class Employee implements Serializable {
    
    @Id
    @Column(name="FIRSTNAME", nullable = false)
    private String firstname;

    @Id
    @Column(name="SURNAME", nullable = false)
    private String surname;
    
    @Id
    @Column(name="SEX", nullable = false)
    private String sex;

    @Id
    @Column(name="DUTY", nullable = false)
    private String duty;

    @OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.EAGER, mappedBy="employee")
    private Set<Phone> phones = new HashSet<>();
    
    @Column(name="COLLECTION_DATE")
    @Temporal(TemporalType.DATE)
    private Date collectionDate;


@Entity
public class Phone implements Serializable {
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    
    @Column(name="PHONE_ID")
    private int id;
    
    @Column(name="PHONE_NUMBER")
    private String number;

    @Column(name="PHONE_TYPE")
    private String type;

    @ManyToOne(optional = false)
    @JoinColumns({@JoinColumn(name="FIRSTNAME", referencedColumnName="PHONE_ID"),
                  @JoinColumn(name="SURNAME", referencedColumnName="PHONE_ID"),
                  @JoinColumn(name="SEX", referencedColumnName="PHONE_ID"),
                  @JoinColumn(name="DUTY", referencedColumnName="PHONE_ID")})
    
    private Employee employee;


Can someone help with completing the @ManyToOne, @JoinColumns statement correctly?

I have tried different combinations & online searches but could not find a direct solution to this error.

I am running Java 7, EclipseLink 2.4.x on Windows 7 platform.

Your assistance would be much appreciated.

Many thanks,

George
Re: Need advice on setup Phone ManyToOne JoinColumns Employee Relationship [message #1085879 is a reply to message #1085125] Tue, 13 August 2013 09:41 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

The "name" of the @JoinColumn is the foreign key column name, the "referencedColumnName" is the name of the primary key column in the target object's table. In your case "PHONE_ID" is not the referencedColumnName, it should be "FIRSTNAME" etc, as you have for the "name".

In general having these four field being the Id seems like a very bad idea, use a single generated id instead.


James : Wiki : Book : Blog : Twitter
Re: Need advice on setup Phone ManyToOne JoinColumns Employee Relationship [message #1086671 is a reply to message #1085879] Wed, 14 August 2013 10:34 Go to previous messageGo to next message
George Jackson is currently offline George Jackson
Messages: 6
Registered: March 2013
Junior Member
Hi James,

Thank you for offering your support to this query.

I have updated the @ManyToOne, @JoinColumns in Phone owning bidirectional entity below without making but the same syntax error persists still:

    @ManyToOne(optional = false)
    @JoinColumns({@JoinColumn(name="FIRSTNAME", referencedColumnName=" FIRSTNAME "),
                  @JoinColumn(name="SURNAME", referencedColumnName=" SURNAME "),
                  @JoinColumn(name="SEX", referencedColumnName="SEX"),
                  @JoinColumn(name="DUTY", referencedColumnName="DUTY")})

An equivalent @ManyToOne using @JoinTable Unidirectional on the Employee entity below has successfully populated both EMPLOYEE & PHONE tables:

    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch=FetchType.EAGER)
    @JoinTable(name="EMPLOYEE_PHONE", catalog="CorporateDB", schema="",
           joinColumns={@JoinColumn(name="FIRSTNAME", referencedColumnName="FIRSTNAME"),
                        @JoinColumn(name="SURNAME", referencedColumnName="SURNAME"),
                        @JoinColumn(name="SEX", referencedColumnName="SEX"),
                        @JoinColumn(name="DUTY", referencedColumnName="DUTY")},
           inverseJoinColumns={@JoinColumn(name="PHONE_ID", referencedColumnName="PHONE_ID")})


I am trying to come up with an equivalent of @JoinTable declaration with @JoinColumns without success so far. JoinTable makes SQL select more complex.

Btw, is inverseJoinColumns necessary and what is the syntax for including it into @JoinColumns declaration above?

Your advice would be much appreciated.

Thanks,

George
Re: Need advice on setup Phone ManyToOne JoinColumns Employee Relationship [message #1087086 is a reply to message #1086671] Thu, 15 August 2013 01:31 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom Eugelink
Messages: 807
Registered: July 2009
Senior Member
My two cents: if in any way possible, start using technical keys.
IOW, give employee an employee_id as the primary or as an unique / alternate key, and add an employee_id field to employee_phone as the foreign key.
This way of defining relations is not only hard to map, but also a big change of performance issues; multiple string fields in foreign keys is very bad for join speeds.


On 2013-08-14 16:34, George Jackson wrote:
> Hi James,
>
> Thank you for offering your support to this query.
>
> I have updated the @ManyToOne, @JoinColumns in Phone owning bidirectional entity below without making but the same syntax error persists still:
>
> @ManyToOne(optional = false)
> @JoinColumns({@JoinColumn(name="FIRSTNAME", referencedColumnName=" FIRSTNAME "),
> @JoinColumn(name="SURNAME", referencedColumnName=" SURNAME "),
> @JoinColumn(name="SEX", referencedColumnName="SEX"),
> @JoinColumn(name="DUTY", referencedColumnName="DUTY")})
> An equivalent @ManyToOne using @JoinTable Unidirectional on the Employee entity below has successfully populated both EMPLOYEE & PHONE tables:
>
> @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch=FetchType.EAGER)
> @JoinTable(name="EMPLOYEE_PHONE", catalog="CorporateDB", schema="",
> joinColumns={@JoinColumn(name="FIRSTNAME", referencedColumnName="FIRSTNAME"),
> @JoinColumn(name="SURNAME", referencedColumnName="SURNAME"),
> @JoinColumn(name="SEX", referencedColumnName="SEX"),
> @JoinColumn(name="DUTY", referencedColumnName="DUTY")},
> inverseJoinColumns={@JoinColumn(name="PHONE_ID", referencedColumnName="PHONE_ID")})
>
> I am trying to come up with an equivalent of @JoinTable declaration with @JoinColumns without success so far. JoinTable makes SQL select more complex.
>
> Btw, is inverseJoinColumns necessary and what is the syntax for including it into @JoinColumns declaration above?
>
> Your advice would be much appreciated.
>
> Thanks,
>
> George
>
Re: Need advice on setup Phone ManyToOne JoinColumns Employee Relationship [message #1087323 is a reply to message #1087086] Thu, 15 August 2013 09:19 Go to previous messageGo to next message
George Jackson is currently offline George Jackson
Messages: 6
Registered: March 2013
Junior Member
Razz Hi Tom,

Thanks for your two cents advice.

Please provide more detail on technical keys and what does IOW stands for? Also, are you against the use of @joinColumns in favour of @joinTable in general, or only the fact that multiple string fields as foreign keys in @joinColumns table will have an impact on query searches?

I am not clear how to construct a SQL select query of Phone.number via Employee entity when using an intermediate table such as EMPLOYEE_PHONE, let alone the possibility of nested queries and potential performance impact.

In short, what is wrong with the @ManyToOne, @JoinColumns declaration which is still encountering the same "@JoinColumns.value is not an annotation type"?

Your valuable input would be much appreciated.

Thanks,

George
Re: Need advice on setup Phone ManyToOne JoinColumns Employee Relationship [message #1087496 is a reply to message #1087323] Thu, 15 August 2013 14:42 Go to previous message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1018
Registered: July 2009
Senior Member
The error doesn't seem like one EclipseLink would throw, and there is no indication that you have a @JoinColumns.value annotation specified in the code you've shown, so I don't know where that would be coming from. What you have shown is almost the same as what is used everywhere, with one difference - the referencedColumnNames being used seems to have spaces in it where as the jointable's referencedColumnNames do not. This could be a cut and paste issue and unrelated to the exception, but they need to match exactly the column names used in the referenced table exactly in both cases.

As has been suggested, you should try putting in a single field in Employee that you can use as the ID. It shouldn't make much difference in this error, but will simplify the model so that you can get it working and then build it back if needed. Try just using the SURNAME for instance and see if you still get the error, as it would help rule out your use of the @JoinColumns as being part of the problem. If you still get the issue, post the exception and more details on where it is coming from, such as a stack if it is a runtime exception.

As for using a relation table such as EMPLOYEE_PHONE - JPQL and criteria queries are ignorant to the fact that there is a relation table, so you would create your queries as if it weren't there, using just Employee.phones in your queries. JPA will translate the relation into SQL and do the join for you.

You will probably need to look at the model needed for business purposes and how it will be used before worrying about performance too much. Optimizations have tradeoffs, so it helps to know how it will be used and understand exactly what you need beforehand.

[Updated on: Thu, 15 August 2013 14:43]

Report message to a moderator

Previous Topic:Changing schema of ClassDescriptor in Container
Next Topic:Adding/removing relations
Goto Forum:
  


Current Time: Tue Sep 02 00:27:37 EDT 2014

Powered by FUDForum. Page generated in 0.02295 seconds