The error speaks for itself, to refer to a composite primary key, you need a complex foreign key. (The composite primary key indicates that you need a unique combination of 2 fields to create a key - then you cannot refer to a unique key in just 1 column.)
As for how this is achieved using xml mapping files, I'm not sure most people use annotations these days.
As for your Java classes, I assume that ImportJobManagement contains ImportJob, so the class should not refer to id, but the object itself, for example:
public class ImportJobManagment implements Serializable { private ImportJob importJob; ... }
Java classes should simply refer to another class, and not to the constituent parts of the composite key - this is a mapping to the mapping from the composite key to a Java member variable.
Response to update:
The short answer is no, you cannot. How a foreign key works, it allows you to refer to a specific row in the table. And, of course, to refer to a specific line, you need a personality to describe only one line and the other. There is a construct in SQL to achieve this, namely a unique key. By stating that a column (or composite column) is unique, you know that its / their combined value will be unique, there will be a maximum of 1 row in the whole table in the whole table, everything else will be in violation of the restriction.
Thus, a foreign key refers to either a single column with a unique constraint or a composite unique key spanning multiple columns. Since all tables already have a unique key, the primary key (which is always unique) is usually used to refer to foreign keys, but any unqiue column will work.
The simplest case is when we want to refer to a table with a unique key with one column. Two simple tables A, which contain one column "id" and B, which contains the column "id", but also another column a_id, which has a foreign key in the column "id" for A. An example of this situation could be this:
A: | id | |----| | 1 | | 2 | | 3 | B: | id | a_id | | 2 | 3 | | 3 | 1 |
Here, each row in B refers to a row in A. Its direct link, the value in a_id in table B corresponds directly to the value in column A '' id '. So B with id 2 refers to A with id 3, etc.
Now let's see how to reference a table with a composite unique key. Let's save our example, but now A has another column "sec_id", which together with "id" constitutes a composite primary key.
A: | id | sec_id | |----|--------| | 1 | 3 | | 3 | 1 | | 3 | 7 | B: | id | a_id | |----|------| | 2 | 3 |
In this situation, we have a problem in B. Since the foreign key must refer to one row in the table, referring to it, this obviously does not work. Which line in represents the value "3"? Sec_id on the first line? The identifier in the second or third (but in this case, which?)? The answer, of course, is not that there is not enough information in B to refer to a single row in A, so there will simply be no SQL. Therefore, adding such a foreign key is not allowed.
In order for B to refer to A, it will require both a reference to the column A 'id'-column and A' sec_id ', since one row in is identified by its unique combination (' id ',' sec_id '). So with B it looks like this:
| id | a_id | a_sec_id | |----|------|----------| | 1 | 1 | 3 | | 2 | 3 | 1 | | 3 | 3 | 7 |
Now B contains enough information to refer to a single line in A, and as the data shows, it does.
Refresh again:
I am currently reading for JPA certification and have reached the chapter on composite key mappings. To display a composite primary key, you need a primary key class that displays the attributes of your key. There are two ways to do this: the one where the key attribute should also appear in the entity itself and the one where it was used as a built-in key.
I will give code examples, they just speak for themselves (using annotations, you really have to do this).
The first example is a basic example with a regular id class (not built-in). Here we have an Employee object, where the primary key consists of an integer identifier and a country (two employees can have the same identifier, if in different countries).
@Entity @IdClass(EmployeeId.class) public class Employee { @Id private String country @Id @Column(name = "EMP_ID") private int id; private String name; ... } public class EmployeeId implements Serializable { private String country; private int id; public EmployeeId() { } public EmployeeId(final String country, final int id) { this.country = country; this.id = id; }
Note:
- @IdClass annotations for the class.
- Both id class attributes must also be defined in essence
- id class should implement equals and hashcode
In another way, this can be done through the built-in id class:
@Entity public class Employee { @EmbeddedId private EmployeeId id; private String name; public Employee(final String country, final int id) { this.id = new EmployeeId(country, id); } public String getCountry() { return id.getCountry(); } } @Embeddable public class EmployeeId { private String country; @Column(name = "EMP_ID") private int id;
Note:
- No need to define id attributes in entity
- To get id class attributes from an entity, you need to get them from the id class
I like the latter better because it is more compact and does not contain duplication, but again I do not know how to use these two comparisons.