I have entity as follow.
#Entity
#Table(name = "BankProduct")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
#ManyToOne
private ProductUseType type;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#ManyToOne
private ProductSerial serial;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ProductUseType getType() {
return type;
}
public void setType(ProductUseType type) {
this.type = type;
}
public ProductSerial getSerial() {
return serial;
}
public void setSerial(ProductSerial serial) {
this.serial = serial;
}
}
My controller is :
#RestController
public class DEmoController {
#Autowired
private ProductRepository productRepository;
#GetMapping("/products")
public Returns products() {
return new Returns(ReturnStatus.SUCCESS.getStatus(), productRepository.findAll(), null);
}
}
It will load both of type and serial of product.
Can I only load type but not to load serial?
I don't want to add fetch=FetchType.LAZY to serial, because if next time I want to load serial but not to load type, it will be terrible.
Check the Projection interface
Create a interface ProductProjection
interface ProductProjection {
String getName();
String getType();
}
and add a method in you Repository
List<ProductProjection> findAllProjection()
That's the whole point of fetch=FetchType.LAZY. It'll not load any of your types/fields until you ask for them explicitly.
Take a look at this question: Link
Related
I have a next question: while working with Hibernate 3.3.0 run into a situation when I have two tables with one-to-many relationships and I need to get the list of parents. In each entity must be filled the several fields from the parent table and a list of all children mapped in the parent. For the easiest understanding, I give an example. I have two tables with one-to-many relationships: parent is "recipients" and child is "requisites". And I have two classes whose objects are the rows of these tables. Class for the table of recipients:
#Entity
#Table(name = "recipients")
#JsonFilter(value = "recipientsFilter")
public class POJORecipient implements POJO {
private static final long serialVersionUID = 4436819032452218525L;
#Id
#Column
private long id;
#Version
#Column
private long version;
#Column(name = "client_id")
private long clientId;
#Column
private String inn;
#Column
private String name;
#Column(name = "rcpt_country_code")
private String rcptCountryCode;
#Column(name = "rcpt_passp_ser")
private String rcptPasspSer;
#Column(name = "rcpt_passp_num")
private String rcptPasspNum;
#OneToMany(mappedBy = "recipient", fetch = FetchType.LAZY)
#JsonManagedReference
private Set<POJORequisite> requisites = new HashSet<>();
public POJORecipient(){}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
public long getClientId() {
return clientId;
}
public void setClientId(long clientId) {
this.clientId = clientId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInn() {
return inn;
}
public void setInn(String inn) {
this.inn = inn;
}
public String getRcptCountryCode() {
return rcptCountryCode;
}
public void setRcptCountryCode(String rcptCountryCode) {
this.rcptCountryCode = rcptCountryCode;
}
public String getRcptPasspSer() {
return rcptPasspSer;
}
public void setRcptPasspSer(String rcptPasspSer) {
this.rcptPasspSer = rcptPasspSer;
}
public String getRcptPasspNum() {
return rcptPasspNum;
}
public void setRcptPasspNum(String rcptPasspNum) {
this.rcptPasspNum = rcptPasspNum;
}
public Set<POJORequisite> getRequisites() {
return requisites;
}
public void setRequisites(Set<POJORequisite> requisites) {
this.requisites = requisites;
}
}
and for requisites table:
#Entity
#Table(name = "requisites")
public class POJORequisite implements POJO {
private static final long serialVersionUID = -35864567359179960L;
#Id
#Column
private long id;
#Version
#Column
private long version;
#Column
private String bic;
#Column
private String bill;
#Column
private String comments;
#Column
private String note;
#ManyToOne
#JoinColumn(name = "recipient_id")
#JsonBackReference
private POJORecipient recipient;
public POJORequisite(){}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
public String getBic() {
return bic;
}
public void setBic(String bic) {
this.bic = bic;
}
public String getBill() {
return bill;
}
public void setBill(String bill) {
this.bill = bill;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public POJORecipient getRecipient() {
return recipient;
}
public void setRecipient(POJORecipient recipient) {
this.recipient = recipient;
}
}
So, I want to select from the recipients only names and all mapped requisites. Consequently, after the selection, I will have a list of POJORecipient objects and in each object filled only the field "name" and set of POJORequisite objects.
As answer of my question I want to discover one of next: how can I do that with help HQL or Criteria API (the second variant is preferable), or understand it is impossible in Hibernate at all, or that this possibility appeared in later versions (also preferably with example). I'm trying to resolve this question for several months now and will be immensely grateful for any help. All clarifications and advices also will be so helpful. Thanks in advance!!!
I'm trying to get the affected rows on insert. I've seen some solution on how to do it but I don't know how to apply it on my code. I'm using spring boot and I haven't mastered it yet. This is my sample code:
Model:
#Entity
#Table(name="test_table")
public class TestTable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name")
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Repository:
public interface TestTableRepository extends CrudRepository<TestTable, Long> {
}
Service:
public interface TestTableService {
public void saveOrUpdate(TestTable testTable);
}
Service Impl:
#Override
public void saveOrUpdate(TestTable testTable) {
testTableRepository.save(testTable);
}
There are some unique rows so I need to know if it inserted or not.
Hoping you could help me. Thank you
I'm new to Java and even more newer to Spring (Boot and JPA) but I was curious, I'm trying to debug an issue that says, "No identifier specified for entity".
For illustartion purposes, I've created the following tables from this diagram:
Originally, there was a M:N relationship between the user and vehicle table, so I created an associative entity (UserVehicleAsso) to split the two up. I was following this guide on M:N mapping in Java, http://viralpatel.net/blogs/hibernate-many-to-many-annotation-mapping-tutorial/
For the most part, it was pretty straight forward but my question is, within the associative entity (UserVehicleAsso), do I have to use the #Id annotation for each of the foreign keys? I assume that I didn't need to because those were automatically generated from each of the respective tables.
Let me know your thoughts or comments, thanks.
Also, below is the code that I used to generate these models:
For the User table/class:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int userId;
private String fName;
private String lName;
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name="userVehicleAsso",
joinColumns={#JoinColumn(name="userID")},
inverseJoinColumns={#JoinColumn(name="vehicleID")})
private Set<Vehicle> vehicles = new HashSet<Vehicle>();
//constructor
protected User() {}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getFName() {
return fName;
}
public void setFName(String fName) {
this.fName = fName;
}
public String getLName() {
return lName;
}
public void setLName(String lName) {
this.lName = lName;
}
public Set<Vehicle> getVehicles() {
return vehicles;
}
public void setVehicles(Set<Vehicle> vehicles) {
this.vehicles = vehicles;
}
#Override
public String toString() {
return getFName() + "," + getLName();
}}
For the Vehicle table/class:
#Entity
public class Vehicle {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int vehicleId;
private String brand;
private String model;
//foreign key mappings
//mapping with associative
#ManyToMany(mappedBy="vehicles")
private Set<User> users = new HashSet<User>();
//constructors
protected Vehicle() {}
public Vehicle(int id) {
this.vehicleId = id;
}
public Vehicle (String brand, String model) {
this.brand = brand;
this.model = model;
}
/* public Vehicle() {
}*/
public int getVehicleId() {
return vehicleId;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
#Override
public String toString() {
// + setBodyType() + "," +
return getBrand() + "," + getModel();
}
}
And then finally, my associtive table/class:
#Entity
public class UserVehicleAsso{
private int userID;
private int vehicleID;
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
public int getVehicleID() {
return vehicleID;
}
public void setVehicleID(int vehicleID) {
this.vehicleID = vehicleID;
}
}
In my opinion, it's not necessary to have an Entity class for the middle table in your case. The table will be generated automatically if configured correctly. In this table, there would not be column ID, only two columns with userID and vehicleID data.
Now, if your middle table has more than what are needed to establish the M:N relationship, then your middle Entity class is needed, and the ID of it, too. For example, if this class is intended to store the time stamp every time a relationship is established, you have to:
Create this Entity class,
Give it an ID field with proper generation strategy,
Map the time stamp with a field with adequate type, annotation/XML mapping and so on.
This part of JPA/Hibernate have confused me a lot and I used to get into them. If my memory serves me well this is the proper/perfect way how things should work.
You can specify a composite primary key class that is mapped to multiple fields or properties of the entity.
Here are sample codes:
public class ActivityRegPK implements Serializable {
private int activityId;
private int memberId;
public int getActivityId() {
return activityId;
}
public void setActivityId(int activityId) {
this.activityId = activityId;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
}
associtive table/class:
#IdClass(ActivityRegPK.class)
#Entity
#Table(name="activity_reg")
#NamedQuery(name="ActivityReg.findAll", query="SELECT a FROM ActivityReg a")
public class ActivityReg implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="activity_id")
private int activityId;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="ins_date")
private Date insDate;
#Id
#Column(name="member_id")
private int memberId;
}
Activity.class
#Entity
#NamedQuery(name="Activity.findAll", query="SELECT a FROM Activity a")
public class Activity implements Serializable {
// some attributes
}
I have three tables :
1. org,
2. product_info
3. service_info.
And, table product_info is mapping table service_info ManyToMany,
means,many products mapping many services.
While,table org is mapping table product_info OneToMany,
means,one org have many products.
When I initialize my web
I want to view the org table's column. How to do ?
Under classes are the persistent classes for three tables.
ProductService class:
`
#Entity
#Table(name="product_service")
#Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class ProductService implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private ServiceInfo serviceInfo;//this is the service table
private String parammapping;
private ProductInfo productInfo;//this is the product table
// Constructors
/** default constructor */
public ProductService() {
}
/** minimal constructor */
public ProductService(String id) {
this.id = id;
}
// Property accessors
#Id
#Column(name="ID", unique=true, nullable=false, length=50)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="SERVICEID")
public ServiceInfo getServiceInfo() {
return this.serviceInfo;
}
public void setServiceInfo(ServiceInfo serviceInfo) {
this.serviceInfo = serviceInfo;
}
#Column(name="PARAMMAPPING", length=1000)
public String getParammapping() {
return parammapping;
}
public void setParammapping(String parammapping) {
this.parammapping = parammapping;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="PRODUCTID")
public ProductInfo getProductInfo() {
return this.productInfo;
}
public void setProductInfo(ProductInfo productInfo) {
this.productInfo = productInfo;
}
}`
baseOrg class:
#Entity
#Table(name="base_org")
#Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class BaseOrg implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String code;
private String name;
private List<BaseRuleEngineLog> serviceUsedLogs = new ArrayList<BaseRuleEngineLog>(0);
private List<ProductInfo> productInfos = new ArrayList<ProductInfo>(0);
private List<BaseCreditQuery> baseCreditQueries = new ArrayList<BaseCreditQuery>(0);
// Constructors
/** default constructor */
public BaseOrg() {
}
/** minimal constructor */
public BaseOrg(String id) {
this.id = id;
}
#Id
#Column(name="ID", unique=true, nullable=false, length=50)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#Column(name="CODE", length=50)
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
#Column(name="NAME", length=200)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="baseOrg")
public List<BaseRuleEngineLog> getServiceUsedLogs() {
return this.serviceUsedLogs;
}
public void setServiceUsedLogs(List<BaseRuleEngineLog> serviceUsedLogs) {
this.serviceUsedLogs = serviceUsedLogs;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="baseOrg")
public List<ProductInfo> getProductInfos() {
return this.productInfos;
}
public void setProductInfos(List<ProductInfo> productInfos) {
this.productInfos = productInfos;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="baseOrg")
public List<BaseCreditQuery> getBaseCreditQueries() {
return this.baseCreditQueries;
}
public void setBaseCreditQueries(List<BaseCreditQuery> baseCreditQueries) {
this.baseCreditQueries = baseCreditQueries;
}
}
productInfo class:
#Entity
#Table(name="product_info")
#Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class ProductInfo implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private BaseOrg baseOrg;//baseOrg table
private String code;
private String name;
private String orgcode;
private List<ProductService> productServices = new ArrayList<ProductService>(0);
// Constructors
/** default constructor */
public ProductInfo() {
}
/** minimal constructor */
public ProductInfo(String id) {
this.id = id;
}
// Property accessors
#Id
#Column(name="ID", unique=true, nullable=false, length=50)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="ORGID")
public BaseOrg getBaseOrg() {
return this.baseOrg;
}
public void setBaseOrg(BaseOrg baseOrg) {
this.baseOrg = baseOrg;
}
#Column(name="CODE", length=100)
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
#Column(name="NAME", length=100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="ORGCODE", length=100)
public String getOrgcode() {
return this.orgcode;
}
public void setOrgcode(String orgcode) {
this.orgcode = orgcode;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="productInfo")
public List<ProductService> getProductServices() {
return this.productServices;
}
public void setProductServices(List<ProductService> productServices) {
this.productServices = productServices;
}
}
serviceInfo class
#Entity
#Table(name="service_info")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class ServiceInfo implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private String code;
private List<ProductService> productServices = new ArrayList<ProductService>(0);
// Constructors
/** default constructor */
public ServiceInfo() {
}
/** minimal constructor */
public ServiceInfo(String id) {
this.id = id;
}
// Property accessors
#Id
#Column(name="ID", unique=true, nullable=false, length=50)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#Column(name="NAME", length=100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="CODE", length=100)
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="serviceInfo")
public List<ProductService> getProductServices() {
return this.productServices;
}
public void setProductServices(List<ProductService> productServices) {
this.productServices = productServices;
}
}
product_service table
Thank you for forgiving my poor English,this is my first time questioning on Stack Overflow.
OK,I resolve it.
i found its so sample,lol.
Because,most criteria have been packaged.At the first time ,I want to use the HQL to resolve it,but in vain.I just add this sentences,and getted it.
enter image description here
First post to stackoverflow, so please excuse if I did not post correctly. I posted a follow-up question with code on an old thread Mapping value in junction table to Entity as I am not able to get the recommended solution to function properly. I am using OpenXava and receive error "Impossible to execute Save action: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of org.openxava.invoicing.model.CourseAssignmentId.course". Any help is appreciated. My code:
User Class:
#Entity
#Table(name="users")
public class User {
#Id
#Column(name="pk1")
private Long id;
public Long getid() {
return id;
}
public void setid(Long id) {
this.id = id;
}
#Column(name="user_id")
private String userID;
public String getuserID(){
return userID;
}
public void setuserID(String userID) {
this.userID = userID;
}
#OneToMany(mappedBy="user")
private Collection<CourseAssignment> courseAssignments;
public Collection<CourseAssignment> getcourseAssignments() {
return courseAssignments;
}
public void setcourseAssignments(Collection<CourseAssignment> courseAssignments) {
this.courseAssignments = courseAssignments;
}
}
Course Class:
#Entity
#Table(name="courses")
public class Course {
#Id
#Column(name="pk1")
private Long id;
public Long getid() {
return id;
}
public void setid(Long id) {
this.id = id;
}
#Column(name="course_name")
private String name;
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
#OneToMany(mappedBy = "course")
private Collection<CourseAssignment> courseAssignments;
public Collection<CourseAssignment> getcourseAssignments() {
return courseAssignments;
}
public void setcourseAssignments(Collection<CourseAssignment> courseAssignments) {
this.courseAssignments = courseAssignments;
}
}
CourseAssignment Class:
#Entity
#Table(name="course_users")
#IdClass(CourseAssignmentId.class)
public class CourseAssignment {
#Id
#ManyToOne
#JoinColumn(name="user_pk1")
private User user;
public User getuser() {
return user;
}
public void setuser(User user) {
this.user = user;
}
#Id
#ManyToOne
#JoinColumn(name="crsmain_pk1")
private Course course;
public Course getcourse() {
return course;
}
public void setcourse(Course course) {
this.course = course;
}
#Column(name="role")
private String role;
public String getrole() {
return role;
}
public void setrole(String role) {
this.role = role;
}
}
CourseAssignmentId Class:
#Embeddable
public class CourseAssignmentId implements java.io.Serializable {
private static final long serialVersionUID = 1L;
#Column(name="user_pk1")
private Long user;
public Long getuser() {
return user;
}
public void setuser(Long user) {
this.user = user;
}
#Column(name="crsmain_pk1")
private Long course;
public Long getcourse() {
return course;
}
public void setcourse(Long course) {
this.course = course;
}
}
Some things to try:
Removing the #Embeddable annotation from CourseAssignmentId (I don't think it is appropriate in this context)
Removing the #Column annotations from CourseAssignmentId
Implementing equals() and hashCode() in CourseAssignmentId