Using Spring Framework JPA I have an Entity
#Entity
#IdClass(ComposityKey.class)
#Table(name="table1")
public class Table1 {
#Id
#Column(name="tableId)
private int tableId;
#Id
private int tableId2;
...
}
2nd Entity contains a reference to Table1
#Entity
#Table(name = "table2")
public class Table2 {
#ManyToOne
#JoinColumn(name="tableId")
private Table1 table1;
}
Now I'm getting the obvious AnnotationException
A Foreign key refering Table1 from Table2 has the wrong number of column. should be 2
Table2 doesn't have tableId2 as a value
So how can i JoinColumn on a Composite Key?
Related
I have two tables A and B. There are two columns in table A, col1 and col2(both the columns are primary key, i.e. composite with col1 and col2). There is one column in table B, to which both the columns from table A are pointing to, i.e. col1 and col2 are foreign keys with relation to column in table B.
How can I implement the JPA entity for table A?
Thank you
Well you can achieve that by following code:
#Embeddable
public class AID {
public int xID;
public int yId;
}
#Entity
public class A {
#EmbeddedId
public AID id;
#OneToMany(mappedBy="A")
public Collection<B> b;
}
#Entity
public class Meeting {
#ID
#GeneratedValue
public Long id;
#MapsId("aID")
#JoinColumns({
#JoinColumn(name="xID", referencedColumnName="xID"),
#JoinColumn(name="yId", referencedColumnName="yId")
})
#ManyToOne
public A a;
}
I'm using PostgreSQL 9.6 with Hibernate 5.2.10 and have 3 entities:
#Entity
#Table(name = "entity1")
public class Entity1 {
#Id
private long id;
#ManyToOne
#JoinColumn(name = "entity2_id")
private Table2 table2;
}
#Entity
#Table(name = "entity2")
public class Entity2 {
#Id
private long id;
#ManyToOne
#JoinColumn(name = "entity3_id")
private Table3 table3;
}
#Entity
#Table(name = "entity3")
public class Entity3 {
#Id
private long id;
}
I need to all delete the occurencies of Entity1 when it joins Entity2 filtering by Entity3, like this:
em.createQuery("delete from Entity1 e where e.entity2.entity3 = :entity3")
And Hibernate generates the following SQL:
delete from entity1 cross join entity2 entity2_ where entity3_id=?
The problem is that PostgreSQL does not recognized the cross join and I didn't find any other way to do this (other than using native query).
PS: in the database all the tables have foreign keys.
Now I found that it's not possible to use joins in delete queries (actually a was migrating from EclipseLink to Hibernate and on EclipseLink it worked, just on Hibernate it doesn't).
Hibernate Exception on MySQL Cross Join Query
I have a similar table structure to the following:
Table_A(
a_id,
data,
primary key(a_id)
)
Table_B(
b_id,
a_id,
data,
primary key (b_id),
foreign key (a_id) references Table_A(a_id)
)
There is a one to many relationship between Table_A and Table_B. My question is, if I have an entity for each of these tables, where:
Entity Table_A is composed of a list of Table_B entities and
Entity Table_B does not necessarily need a reference to Table_A (just the fields b_id, a_id, data)
is it possible to annotate these entities in a way where I can persist a Table_A entity and the process will implicitly persist all Table_B entities with the value of the new generated Table_A primary key a_id.
Thanks in advance.
Here is what I have essentially . But I get the below exception. Looks like Table_B is being persisted prior to Table_A, therefore no a_id value exists.
#Entity
public class Table_A {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "a_id")
private Integer id;
#OneToMany (cascade = CascadeType.PERSIST)
#JoinColumn(name="a_id")
private List<Table_B> bList;
private String data;
}
#Entity
public class Table_B {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "b_id")
private Integer id;
private String data;
}
ERROR: null value in column "a_id" violates not-null constraint
Detail: Failing row contains (null, Testing, 16)
Yes, with a cascade set to PERSIST on the OneToMany association.
Note that you shouldn't have aId in the B entity. Either make the association bidirectional, and have a field of type TableA, or leave it unidirectional and don't have any field in B mapped to a_id.
EDIT: AFAIR, you need to tell Hibernate that the column is not null, else it tries to insert everything first, and then populate the foreign keys:
#OneToMany (cascade = CascadeType.PERSIST)
#JoinColumn(name="a_id", nullable=false)
private List<Table_B> bList;
#OneToMany(mappedBy = "a_id", cascade = CascadeType.PERSIST)
instead of
#OneToMany(cascade = CascadeType.PERSIST) #JoinColumn(name="a_id")
Eclipselink generated a create table statement like so:
Create Table myTable (ID (255) not null, col1 (255), col2(255), col3(255) PK (ID, col1, col2)
#Embeddable
MyPK implements Serializable
{
#OneToOne
#Id
String col1;
#OneToOne
#Id
String col2;
...
}
#Entity
MyClass implements Serializable
{
#EmbeddedId
MyPK pk;
String col1;
String col2;
String col3;
...
}
How do I prevent the generation of the ID column in the Create Table statement? I ask because em.persist(MyClass) throws a constraint exception on ID being null. I expected that the #EmbeddedId would override this and prevent that field from being created.
EDIT
The table that I am trying to generate in code looks like so:
fk - col1
fk - col2
VarChar - col3
First issue is a String attribute can not be a OneToOne mappings. Second a OneToOne mapping can not be used within an EmbeddedId. Third you do not use the #Id annotation within an EmbeddedId as an Embeddable can not have identity.
The easiest way to do this is:
#Entity
#IdClass(MyPK.class)
MyClass implements Serializable
{
#OneToOne
#Id
TargetClass rel1;
#OneToOne
#Id
SecondTargetClass rel2
#Basic
String col3;
...
}
MyPK implements Serializable
{
String rel1;
String rel2;
...
}
If you really need an Embeddable for the pk class then replace the #ID annotation with #MapsId and add the EmbeddedId annotation back in MyClass and the Embeddable annotation back to MyPK
I have 2 entities for legacy db with composite keys, one of them has a composite key with #EmbeddedId annotation.
// first entity
#Entity
public class Product {
#Id
private Integer productId;
// lookup table contains code-description pairs
#OneToOne
private ProductDefects defects;
//getters and setters and other code omitted
}
// lookup entity
#Entity
public class ProductDefects {
#EmbededId
private ProductDefectsPK id;
//getters and setters and other code omitted
}
//composite key
#Embedable
public class ProductDefectsPk{
private Integer realId;
private String category;
}
How should I define the #OneToOne relation to join as in the following example:
select p.Id, pd.description
from Product p
inner join p.defects pd
I figure out that #MapsId annotation helps in my case http://download.oracle.com/javaee/6/api/javax/persistence/MapsId.html