I want to make connection between Product class and Laptop
Product class
#Entity
#Table(name = "products")
#Inheritance(strategy = InheritanceType.JOINED)
public class Product {
#Id
#Column(unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(nullable = false, unique = true)
private String name;
#Column(nullable = false)
private BigDecimal cost;
#Column(nullable = false)
private int count;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "productStatus", nullable = false)
private ProductStatus productStatus;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "productManufacture", nullable = false)
private ProductManufacture productManufacture;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "productCategory", nullable = false)
private ProductCategory productCategory;
and
Laptop class
#Entity
#Table(name = "laptops")
public class Laptop extends Product {
#Id
#Column(unique = true, nullable = false)
private int id;
#Column(nullable = false)
private String processor;
private int videoMemory;
#Column(nullable = false)
private int ram;
But my varient doesnt work...( How can I do it right
And how can I insert into database some data?(example please)
Laptop is extending Product class and inherits all the fields from the parent class including ID. You are defining ID again on the Laptop class. Inheritance Strategy is also JOINED which means it handles the Id generation both for the parent and the child class. Remove the Id field and its annotations.
Related
I am studying a training project - working with databases.
Here is a class describing the entity
#Entity
#Table(name = "pricelists", schema = "inventories")
public class PriceList {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "id_inventory", insertable = false, updatable = false)
private Long idInventory;
#ManyToOne
#JoinColumn(name = "id_inventory", nullable = false)
private Inventory inventory;
private Integer price;
}
And there are two variables that refer to the same "id_inventory" field in the database table. Is it possible to do this? Is this not a mistake?
You should leave that
#Entity
#Table(name = "pricelists", schema = "inventories")
public class PriceList {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "id_inventory", nullable = false)
private Inventory inventory;
private Integer price;
}
I hope that will work.
I have the following code for many to many or many to one relationship persistence using Spring JPA.
This is my repository test https://github.com/Truebu/testJpa.git
This class has three one-to-many relationships, but none work well
#Entity(name = "routine_assignament")
#Table(name = "routine_assignament")
public class RoutineAssignament {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", updatable = false)
private Long id;
#Column(name = "date_start",nullable = true,columnDefinition = "DATE")
private Date date_start = new Date();
#Column(name = "date_end",nullable = true,columnDefinition = "DATE")
private Date date_end;
#ManyToOne
#JoinColumn(name = "id_user")
private User user;
#ManyToOne
#JoinColumn(name = "id_routine")
private Routine routine;
#OneToMany(mappedBy = "routine_assignament")
private Set<Score> scores = new HashSet<>();
#OneToMany(mappedBy = "routine_assignament")
private Set<Statistic> statistics = new HashSet<>();
#OneToMany(mappedBy = "routine_assignament")
private Set<KeepRoutine> keepRoutines = new HashSet<>();
The other classes
#Entity(name = "score")
#Table(name = "score")
public class Score {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", updatable = false)
private Long id;
#Column(name = "commentary",nullable = false,columnDefinition = "TEXT", unique = true)
private String commentary;
#Column(name = "assessment",nullable = false,columnDefinition = "INT", unique = true)
private String assessment;
#ManyToOne
#JoinColumn(name = "id_routine_assignament")
private RoutineAssignament routineAssignament;
}
#Entity(name = "statistic")
#Table(name = "statistic")
public class Statistic {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", updatable = false)
private Long id;
#Column(name = "time",nullable = false,columnDefinition = "TEXT", unique = true)
private String time;
#ManyToOne
#JoinColumn(name = "id_routine_assignament")
private RoutineAssignament routineAssignament;
}
and
#Entity(name = "keep_routine")
#Table(name = "keep_routine")
public class KeepRoutine {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", updatable = false)
private Long id;
#ManyToOne
#JoinColumn(name = "id_routine_assignament")
private RoutineAssignament routineAssignament;
}
The entity relationship diagram is this:
My mistake is that it doesn't detect these relationships correctly.
When I run it it generates this:
Failed to initialize JPA EntityManagerFactory: mappedBy reference an unknown target entity property: com.example.demo.model.entities.KeepRoutine.routine_assignament in com.example.demo.model.entities.RoutineAssignament.keepRoutines
This error is reproduced with all three classes (KeepRoutine, Statistic and Score), I don't know why
Your OneToMany mapping is not appropriate. You need to use routineAssignament the property name instead of the table name routine_assignament as shown below. This property name is defined in the ManyToOne relationship.
#OneToMany(mappedBy = "routineAssignament")
private Set<Score> scores = new HashSet<>();
#OneToMany(mappedBy = "routineAssignament")
private Set<Statistic> statistics = new HashSet<>();
#OneToMany(mappedBy = "routineAssignament")
private Set<KeepRoutine> keepRoutines = new HashSet<>();
I have 3 objects with simple relationship which looks as follows:
University:
#Entity
public class University {
#Id
#GeneratedValue
private Long id;
private String name;
}
Faculty:
#Entity
public class Faculty {
#Id
#GeneratedValue
private Long id;
private String name;
#Column(name = "university_id", nullable = false)
private Long universityId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinFetch(value = JoinFetchType.OUTER)
#JoinColumn(name = "university_id", insertable = false, updatable = false, nullable = false)
private University university;
}
Specialty:
#Entity
public class Specialty {
#Id
#GeneratedValue
private Long id;
private String name;
#Column(name = "faculty_id", nullable = false)
private Long facultyId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinFetch(value = JoinFetchType.OUTER)
#JoinColumn(name = "faculty_id", insertable = false, updatable = false, nullable = false)
private Faculty faculty;
}
I am using EclipseLink and Spring CrudRepository to operate with these entities.
When i call
specialtyRepository.findAll();
i get sql
SELECT * FROM specialty LEFT OUTER JOIN faculty ON (faculty.ID = specialty.faculty_id) ...
and extra sql like
SELECT * FROM university WHERE ((ID = ?)) ...
I want to prevent this sql request;
Could someone tell me how to resolve this issue?
Thank you for any tips
For lazy loading in #ManyToOne i must enable dynamic weaving in EclipseLink:
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving
I solved this problem via inheritance;
I have created the base instance without relationship;
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class FacultyBase {
#Id
#GeneratedValue
private Long id;
private String name;
#Column(name = "university_id", nullable = false)
private Long universityId;
}
and instance with relationship
#Entity
public class Faculty extends Faculty {
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "university_id", insertable = false, updatable = false, nullable = false)
private University university;
}
As a result, in Specialty instance i use FacultyBase instead of Faculty
The "TypeMismatchException: Provided id of the wrong type" error thrown when tried to merge detached entity. It works if the object wasn't detached. It also works if ids aren't #EmbeddedId.
A sample repo can be found here https://github.com/joes-code/hibernate-map
// Asset.java
#Entity
#Table(name = "asset")
public class Asset {
#EmbeddedId
private AssetId id;
#Column(name = "asset_cost"
private BigDecimal price;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "asset_id", referencedColumnName = "asset_id", nullable = false, insertable = false, updatable = false, foreignKey = #ForeignKey(ConstraintMode.NO_CONSTRAINT))
private AssetDetail assetDetail;
}
// AssetId.java
#Embeddable
public class AssetId {
#Column(name = "asset_id", nullable = false)
private Integer assetId;
}
// AssetDetail.java
#Entity
#Table(name = "asset_detail")
public class AssetDetail {
#EmbeddedId
private AssetDetailId id;
#Column(name = "description", length = 35)
private String description;
}
// AssetDetailId.java
#Embeddable
public class AssetDetailId {
#Column(name = "asset_id", nullable = false)
private Integer assetId;
}
I'm using Hibernate 5.4.3.Final
Any ideas what I did wrong? It seems that Hibernate is assuming Asset and AssetDetail share the same Id class?
I have an Entity FooBar which serves as the #ManyToMany join table for Foo and Bar entities including some additional information.
#Entity
#Table(name = "foo_bar")
public class FooBar
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, nullable = false)
protected Long id;
#Column(name = "someInfo", nullable = true)
private String someInfo;
#ManyToOne(optional = false)
private Foo foo;
#ManyToOne(optional = false)
private Bar bar;
//getters, setters, and toString()
}
#Entity
#Table(name = "foo")
public class Foo
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, nullable = false)
protected Long id;
#OneToMany(mappedBy = "foo", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<FooBar> fooBars;
//Foo has a number of other fields
#Column(name = "orderIndex", nullable = false)
private int orderIndex;
#Column(name = "upgradeDirection", nullable = false)
#Enumerated(EnumType.STRING)
private Order direction;
#ManyToOne(optional = false)
private SomeEntity e;
//getters, setters, and toString()
}
#Entity
#Table(name = "bar")
public class Bar
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, nullable = false)
protected Long id;
#OneToMany(mappedBy = "bar") //TODO specify a cascade and fetch attribute
private Set<FooBar> fooBars;
//Bar contains a number of other fields
#Column(name = "value", nullable = false)
private String value;
//getters, setters, and toString()
}
When Hibernate creates the table is has columns 'id', 'someInfo', 'foo_id', and 'bar_id'. 'foo_id' and 'bar_id' are used in as a composite key instead of using the 'id' field, any idea why?