How to map one to many JPA relationship? - jpa

I'm getting Unknown column 'imageprope1_.enid' in 'field list' with the following mapping:
#OneToMany(fetch=FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name="enid", referencedColumnName="pnid")
private List<EntityImageProperty> imageProperties = new ArrayList<>();
Here's the key entity mapping:
BaseEntityProperty
#Entity
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorColumn(name="enpptpcd", discriminatorType=DiscriminatorType.STRING)
#Table(name=BaseEntityProperty.TABLE_NAME)
public abstract class BaseEntityProperty implements Serializable {
#Id
#Column(name="enppid")
private String entityPropertyId=null;
#Column(name="enid")
private String entityId=null;
EntityImageProperty
#Entity
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorValue(EntityImageProperty.DISCRIMINATOR_VALUE)
#Table(name=EntityImageProperty.TABLE_NAME)
#PrimaryKeyJoinColumn(name="enppid")
public class EntityImageProperty extends BaseEntityProperty {
It looks like #JoinColumn(name="enid", referencedColumnName="pnid") tells Hibernate to join on EntityImageProperty.enid, whereas it should join on BaseEntityProperty.enid.

Related

JPA composite Foreign Key part of composite Primary Key unable to find ID

We have tables,
'Lin_Code_Groups' with fields,
Project_ID (PK),
CG_ID(PK),
CG_Name
Corresponding entity class,
public class Lin_Code_Groups implements Serializable {
#EmbeddedId
private LinCodeGroupPK pk;
private String CG_name;
#Embeddable
public static class LinCodeGroupPK implements Serializable {
private Integer Project_ID;
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer CG_ID;
}
#OneToMany(mappedBy = "lin_Code_Groups")
private List<Lin_CG_Params> lin_CG_Params;
}
table Lin_CG_Params with fields,
Project_ID (PK)..FK to Lin_Code_Groups,
CG_ID(PK)...FK to Lin_Code_Groups,
Param_name(PK),
Param_value
Corresponding entity class,
public class Lin_CG_Params implements Serializable {
#EmbeddedId
private LinCodeGroupParamPK pk;
private String Param_value;
#Embeddable
public static class LinCodeGroupParamPK implements Serializable {
private String Param_name;
private LinCodeGroupPK linCodeGroupPK;
}
#MapsId("linCodeGroupPK")
#ManyToOne
#JoinColumns( {
#JoinColumn(name = "Project_ID",referencedColumnName= "Project_ID"),
#JoinColumn(name = "CG_ID",referencedColumnName= "CG_ID")
})
private Lin_Code_Groups lin_Code_Groups;
}
in controller class, i am using JPA's .Save method to save the data in to the tables.
#PostMapping(value = {"/hello"}, consumes = "application/json", produces = "application/json")
public ResponseEntity<Object> saveNewCodeGroupsDetails(#RequestBody Lin_Code_Groups objLin_Code_Groups ) {
respository.save(objLin_Code_Groups);
}
but getting an error 'Unable to find Lin_CG_Params with id Lin_CG_Params.LinCodeGroupParamPK'
Can anyone is please help ?

#ManyToOne conflicts with JpaRepository

#ManyToOne or #OneToOne will replace the joined column with an entity, but how would I do when I want to use JpaRepository to query by that joined column? There's seems a conflict.
#Entity
public class Type {
private Long id;
}
#Entity
public class Item {
#ManyToOne
#JoinColumn(name = "type_id")
private Type type;
}
public interface ItemRepository extends JpaRepository<Item, Long> {
List<Item> findByTypeId(Long typeId);
}
It throws error "property typeId not found", which makes sense because it's surely not in the class "item", instead an entity "type". But how could I query Item by type_id in this situation? And if I declare property typeId, it will throw error duplicated mapping for column "type_id".
You have to do it with _ like
public interface ItemRepository extends JpaRepository<Item, Long> {
List<Item> findByType_Id(Long typeId);
}

JPA Criteria to query hierarchy of child objects

I have two tables that are represented by following entity object hierarchies:
#Entity
#Table(name = Transport.TABLE_NAME)
#DiscriminatorColumn(name="transport_type", discriminatorType = DiscriminatorType.INTEGER)
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class Transport {
...
private Date departure;
}
#Entity
#DiscriminatorValue("1")
public class Bicycle extends Transport {
...
#OneToOne(mappedBy = "transport", fetch = FetchType.LAZY)
private BikePassenger passenger;
}
#Entity
#DiscriminatorValue("2")
public class Car extends Transport {
...
#OneToMany(mappedBy = "transport", fetch = FetchType.EAGER)
private List<CarPassanger> passengers;
}
#Entity
#Table(name = Passenger.TABLE_NAME)
#DiscriminatorColumn(name="passenger_type", discriminatorType = DiscriminatorType.INTEGER)
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class Passenger {
...
private int passengerGUID;
}
#Entity
#DiscriminatorValue("1")
public class BicyclePassenger extends Passenger {
...
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "transportid")
private Bicycle transport;
}
#Entity
#DiscriminatorValue("2")
public class CarPassenger extends Passenger {
...
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "transportid")
private Car transport;
}
Now using JPA Criteria API (or at least JPA) how do I:
Get all transports that have passengers with specific passengerGUID?
Group transports (along with passengers) by departure date?
As I see it #1 should have nice solution but I was able to get out only with 2 subselects for each subtype. Which looks ugly to me.
And finally third question - is it good model at all? From OOP point of view to me it looks ok, but from ORM point of view and easiness of queries it looks not so good...
p.s. I'm using hibernate JPA 2.1

composite primary key which contains a foreign key

I have an entity called UserWithRoles:
#Entity
#Getter
#Setter
public class UserWithRoles implements Serializable
{
#Id
#GeneratedValue( strategy = GenerationType.AUTO )
private int id;
private String name;
private String password;
#OneToMany( mappedBy = "user" )
private List<UserRole> roles;
}
A UserRole entity:
#Entity
#Getter
#Setter
#IdClass( UserRolePK.class )
#Inheritance( strategy = InheritanceType.JOINED )
#DiscriminatorColumn( name = "roleType", discriminatorType = DiscriminatorType.STRING, length = 10 )
abstract public class UserRole implements Serializable
{
#Id
// It should be mapped as a foreign PK by user.id (user field declared below)
private int userID;
#Id
private String roleType;
#ManyToOne
#JoinColumn( name="user_id", referencedColumnName = "id" )
private UserWithRoles user;
}
The primary key class UserRolePK:
#Data
public class UserRolePK implements Serializable
{
private int userID;
private String roleType;
}
I want to create a composite PK to UserRole: UserWithRoles.id + UserRole.roleType
How can I map it to the database? Should I use the UserWithRoles type in the PK class instead of the ID? Is it a good idea at all? Or I just should use normal PK to UserRole? The relation would be something like that between the ClientOrder and ClientOrdetItem entities: (ClientOrder.id + ClientOrderItem.num)
You are using Derived Identity.
You need to change UserRole to look like this:
#Entity
#Getter
#Setter
#IdClass( UserRolePK.class )
#Inheritance( strategy = InheritanceType.JOINED )
#DiscriminatorColumn( name = "roleType", discriminatorType = DiscriminatorType.STRING, length = 10 )
abstract public class UserRole implements Serializable
{
#Id
private String roleType;
#Id
#ManyToOne
#JoinColumn( name="user_id", referencedColumnName = "id" )
private UserWithRoles user;
}
That is, get rid of the userID field and add an #Id annotation to the user field.
And change UserRolePK to look like this:
#Data
public class UserRolePK implements Serializable
{
private int user;
private String roleType;
}
That is, change the name of the userID field to user, to match the name of the #Id field in UserRole (but its type must still match the type of the UserWithRoles PK field, id).
Derived identity is discussed in JPA 2.1 spec, section 2.4.1.

using #Embedabble with a foreign key and manyToMany relation

I wrote an example for the code i am trying to implement, i get an error with Constraint "Student_Teacher_FK" already exists.
the #embiddable class has a foreign key that is created twice with current code.
#Entity
public class Teacher {
#Id
#GeneratedValue
private Long id;
#Column(name = "Name")
private String name;
}
#Entity
public class Student{
#Id
#GeneratedValue
private Long id;
#Column(name = "Name")
private String name;
}
#Embeddable
public class StudentList implements Serializable {
#ManyToMany
#JoinTable(name = "Student_Teacher",
joinColumns =
#JoinColumn(name = "Student_ID", referencedColumnName = "ID"),
inverseJoinColumns =
#JoinColumn(name = "Teacher_ID", referencedColumnName = "ID")
)
#ForeignKey(name = "Student_Teacher_FK", inverseName = "Teacher_Student_FK")
public List<Student> studentList = new ArrayList<Student>();
}
#Entity
public class HistoryTeacher extends Teacher {
#Embedded
#NotNull
private StudentList StudentList = new StudentList ();
}
#Entity
public class LangTeacher extends Teacher {
#Embedded
#NotNull
private StudentList StudentList = new StudentList ();
}
#Entity
public class RetiredTeacher extends Teacher {
// has no students
}
#embeddable : Defines a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity (http://docs.oracle.com/javaee/6/api/javax/persistence/Embeddable.html)
As you are declaring it in 2 different entity, jpa will create associated association table (student-teacher) 2 times with associated fk, which is explicitely named, and so created 2 times too with the same name. Here is your error.
I don't think using #embeddable is appropriated for what you're intending to do. A student has is own existence and is not part of teacher itself (not an uml composition / black diamond) so it's not an embeddable entity. Student list should be held by teacher entity using a simple manyToMany association.