Foreign key as primary key annotation - java

There is 2 entity
Product(product_id(PK),product_name..)
Store(product_id(PK,FK),product_quantity,...)
I need #OneToOne, so i do this
public class Product{
#Id
#Column(name="PRODUCT_ID")
#OneToOne(mappedBy="product")
private int product_id;
....
}
public class Store{
#Id
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "PRODUCT_ID")
private Product product;
}
Compilier says #Column(s) not allowed on a #OneToOne property: ......shopdb.entity.Product.product_id
What is the problem?

I just moved #OneToOne(mappedBy="product") to new created field in Product
private Store store;
I dont understand how it works correct;
Why i need to use 3 fields instead of 2?

You can't mark a column defined with #JoinColumn as #Id. This is applicable only to columns defined with #Column annotation.
It is also a bit strange what are you trying to do. You are basically making the produc_id primary key for both entites, so then why don't make just one?
From what I can see here, I believe that the Store should have a store id property which will be used as primary key.

Related

Hibernate-OneToMany mapping for existing DB Tables

I am trying to join to Hibernate Entities in a OneToOne Mapping. I am able to fetch the data for a given primary key from the Main Entity, the joining entity, however, returns null. I am new to hibernate and any help will be appreciated.
I have two Tables,
PT_CORE
Primary Key: ptId - Integer;
Foreign Key: stId(ST_AUX) - Integer;
Columns: ptId, ptName
ST_AUX
Primary Key: stId;
Columns: stId, stName
The two tables get populated by other applications and mine is a read-only operation.
Below is my first Entity class(PtCore.java)
#Entity
#Table(name="PT_CORE")
public class PtCore implements Serializable{
#Id
#Column(name="ptId", nullable = false)
private int id;
#Column(nullable=false)
private int stId; //The Foreign key column
#OneToOne
#JoinTable( name = "core_aux", joinColumns = {#JoinColumn(Name="ptId")},
inverseJoinColumns = {#JoinColumn(Name="stId")}
)
private StAux staux;
//Getters, setters and toString() for above
}
StAux is another Entity, defined as below,
#Entity
#Table(name="ST_AUX")
public class StAux implements Serializable {
#Id
#Column(nullable=false)
private Integer stId;
#OneToOne
private PtCore ptcore;
#Column
private String stName;
//Getters, Setters and toString follow.
}
I do below in the Service method:
PtCore obj = (PtCore) session.get(PtCore.class,1);
System.out.println(obj);
In the Results, I get the value of ptName, but the stAux class variables are null, Indicating that the join does not work as expected.
First of all you have the mapping information existing in your PT_CORE. And I assume it is something like FOREIGN KEY (stid) REFERENCES (stid). If you want to use existing schema and existing data I guess there is no mapping table core_aux really existing. At least you did not mention it. However it is visible as #JoinTable annotation but still there is this above mentioned foreign key which seems to be the real mapping (so again not the join table).
I suggest the following
remove this
#Column(nullable=false)
private int stId; //The Foreign key column
from your PtCore. I think it is not needed. Also in PtCore, remove the #JoinTable (because what I told above) and add mapping informaiion to #OneToOne annotation, like:
#OneToOne
#JoinColumn(name = "stid")
private StAux staux;
from your PT_CORE.
Then in StAux alter also a bit:
#Id
#Column(name = "stid") // this might not be needed but if there is like "st_id"...
private Integer stId; // so just for sure
#OneToOne(mappedBy = "staux")
private PtCore ptcore;
Because you have existing tables and constraints there might raise errors if hibernate tries to auto-generate those again by JPA instructions.
Check this for example for more information.
UPDATE: just realized also that in your title is #OneToMany but in your code is #OneToOne.
So you might want to elaborate your question and/or title a bit.
In your relation, the owning side is PtCore, the inverse side is StAux.
In bidirectional OneToOne relations, the inverse side has to have the mappedBy attribute. Actually, the mappedBy attribute contains the name of the association-field on the owning side.
So, you must change your inverse side code (StAux Entity). You have to add mappedBy attribute to #OneToOne in StAux class:
#OneToOne(mappedBy="staux")
private PtCore ptcore;

Spring and JPA 2.0 - Single value Primary Key through OneToOne

I have a simple table (ActivityLog) and I want it to have a PK that is also a FK to another table (User).
It seems to be a common thing to have, and I tried to follow this wikibook
Primary Keys through OneToOne and ManyToOne Relationships. The example there involved a composite key. I need just a primitive key, so I ended up with:
#Entity
public class User {
#Id
private Long id;
// other stuff
}
#Entity
public class ActivityLog {
#Id
#OneToOne(optional = false)
#JoinColumn(name="user_id", referencedColumnName="id")
private User user;
// other stuff
}
Unfortunately i am getting:
Caused by: java.lang.IllegalArgumentException: This class [class com.example.ActivityLog] does not define an IdClass
at org.hibernate.metamodel.internal.AbstractIdentifiableType.getIdClassAttributes(AbstractIdentifiableType.java:183)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation$IdMetadata.<init>(JpaMetamodelEntityInformation.java:253)
I tried to annotate ActivityLog with:
#IdClass(Long.class)
(even though from what I understand it is applicable only for composite keys), yet I am getting the exact same error.
Is my case different than what's on the mentioned wikibook?
Is Spring at fault here? (As suggested in this question? (no accepted answers)).
This should help:
#Entity
public class ActivityLog {
#Id
#Column(name = "user_id")
private Long id;
#OneToOne(optional = false)
#JoinColumn(name="user_id", referencedColumnName="id")
private User user;
// other stuff
}
Btw. I would expect, that you need more logs per user, so you would probably need some additional (generated) id anyway ...

How to delete entity which associated with java map list

I have an entity which has map list with sub enitities. When I want to delete this entity , I've got
Cannot delete or update a parent row: a foreign key constraint fails (kobalt.category_categoryitem,
error and I use hibernate. Is there anyone who can solve this problem ?
#Entity
public class Product implements BaseEntity {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private int id;
private int kobilId;
private String code;
#Column(unique = true)
private long barcode;
private String productName;
#Column
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#Fetch(value = FetchMode.SUBSELECT)
#Cascade(org.hibernate.annotations.CascadeType.DELETE)
private Map<Category, CategoryItem> itemList;
Looks like relationship structure is not correct in your case. When you are trying to delete foreign key corresponding value it can't delete primary key corresponding value. In cascade rule relationship should be like as when you delete primary key corresponding attribute then it should delete all foreign key corresponding attributes. But can't be vice-versa. That is your case i think so try to correct your relationships. For example consider "employee - address" relationship where employee has array of address. So relationship should be like as when employee is deleted, all the corresponding address should vanish. But on the other hand if relationship is not correct and you try to delete an address then it can't be possible to delete employee, as a result you'll get such exception as in your case.

ManyToMany reflexive relationship with an extra coloumn in JPA

First of all, sorry for my english. This is my first post.
Im developing an app for a friend that uses JPA (EclipseLink) and i can´t figure out how to make a ManyToMany reflexive relationship with an extra column describing the relationship.
I tried the solution of this post (without using a bidirectional relation):
#Entity
#Table(name="relationships")
public class Relationship implements Serializable {
private static final long serialVersionUID = 1L;
#ManyToOne()
#JoinColumn(name = "associated_id_one")
private Person associatedPersonOne;
#ManyToOne()
#JoinColumn(name = "associated_id_two")
private Person associatedPersonTwo;
#Column(name="description")
private String description;
//Getters, Setters and constructor
...
}
But JPA gives me this error: The entity has no primary key attribute defined.
I know i have to specify a primary key but i don´t now how to make a composite primary key with those two foreign key.

Hibernate disable default behaviour

I have a problem with my Hibernate making assumptions on what to call columns.
Specifically, when I do a #ManyToOne field, where I refer to a column in the other Table.
What happens is that, If I do not enter a #JoinColumn annotation as well, it maps the field with an underscore in it's name.
For example, i have this class:
#Entity
public class User extends AbstractEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String username;
private String password;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "userFK")
private List<TwitterAccount> twitterAccounts;
/* GETTERS & SETTERS OMITTED */
}
And then I have the TwitterAccount class:
#Entity
public class TwitterAccount extends AbstractEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#ManyToOne(fetch = FetchType.LAZY)
private User userFK;
}
What happens is that when it tries to get the Twitter accounts for a certain user, I get the exception: MySQLSyntaxErrorException: Unknown column 'twitteracc1_.userFK_id' in 'field list'
Look at what it tries to map the userFK to: userFK_id. Of course it doesn't exist! I haven't given it that name.
So the question comes down to: Is it possible to turn off this functionality? (The functionality that turns the column name into 'field_'foreignkey')
I am aware that using #JoinColumn(name = "userFK") would solve it, but I'd rather turn it off instead.
Regards
This is the default as specified by the JPA specification
The concatenation
of the following: the name
of the referencing relationship
property or field of the referencing
entity or embeddable class;
""; the name of the referenced
primary key column. If there is no
such referencing relationship
property or field in the entity, or if
the join is for an element collection,
the join column name is
formed as the concatenation of the
following: the name of the entity;
""; the name of the referenced
primary key column.
In hibernate this is implemented in a NamingStrategy in this case the EJB3NamingStrategy. You can implement your own version of this deciding whatever you want to use. But that will probably only complicate/confuse people (which might expect the standards to apply).

Categories