I am new to Hibernate and I am using it with Spring. I have the following tables:
#Entity
#Configurable
public class Location {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long locationid;
private String locationName;
#ManyToOne
private Site site;
//getters setters skipped
}
#Entity
#Configurable
public class Site {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long siteid;
private String siteName;
#ManyToOne
private Country country;
//getters setters skipped
}
#Entity
#Configurable
public class Country {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long countryid;
private String countryName;
#ManyToOne
private Region region;
//getters setters skipped
}
#Entity
#Configurable
public class Region {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long regionid;
private String regionName;
//getters setters skipped
}
public class Assets {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long assetId;
#ManyToOne
private Location location;
//getters setters skipped
}
I want to pull all assets based on Regions. How should I do that?
How do I use the relationship between Region --> Country --> Site --> Location and pull the relevant records? How do I do it without affecting the performance?
Or should I just redesign the tables?
You can just complete it by a #NamedQuery in the class Assets :
select a from Asserts a where a.location.site.contry.regin.reginName = :reginName
Hope help.
Related
I am using Spring Boot with Spring Data JPA. I have two tables named User and Employee.
Employee.java
#Data
#NoArgsConstructor
public class Employee implements Serializable
{
private static final long serialVersionUID = -3732596549369515261L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String designation;
private Date dateOfJoining;
private String workLocation;
#Column(unique = true)
private Long contactNo;
#Column(unique = true)
private String email;
private Date dateOfLeaving;
}
User.java
#Entity
#Data
#NoArgsConstructor
public class User
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;
private String password;
}
I want to create a relation between Employee.email with User.username. Will this be possible via any JPA annotations.
I tried with Mappings from JPA and none of them is working as the User.username is String, unlike Employee object.
I would like to make a unique field "number" with autogeneration(autoincrement, last number + 1). But it is not an id field. How can i reach that? #GeneratedValue doesn't work. Only id was generated. My code doens't work.
My entity
#Entity
#Table(schema = "public")
public class Policeman implements Serializable {
#Id
#GeneratedValue
private Long id;
#Column
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long number;
#Column
private String fam;
#Column
private String name;
#Column
private String otch;
//setters getters
}
This SO question looked the same: Link1
It says that the #GeneratedValue annotation is only used in conjunction with #Id to create auto-numbers. It cannot be used with non-id columns. However, there is a workaround that suggests to create a separate entity with a generated Id, something like this:
#Entity
public class GeneralSequenceNumber {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long number;
}
#Entity
#Table(schema = "public")
public class Policeman implements Serializable {
#Id
#GeneratedValue
private Long id;
#OneToOne(...)
private GeneralSequnceNumber myVal;
#Column
private String fam;
#Column
private String name;
#Column
private String otch;
//setters getters
}
You can also refer to the following link for more details on this work-around:Link2
I hope it helps.
So here is an example close to my actual code:
#Entity
#Table(name="Products")
#Data
public class Product{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="productno")
private long ID;
#Column(name="name")
private String productName;
private ProductCategory category;
}
#Entity
#Table(name="Category")
#Data
public class ProductCategory{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="categoryno")
private long ID;
#Column(name="name")
private String categoryName;
#OneToMany
#JoinColumn(name="category")
private List<Product> product;
}
aswell as a thymeleaf template, that displays a bunch of those in a table using th:each
and a controller that sends the data to those templates. Those templates have been tested and they should work.
the problem is, when bootRunning and opening the page, i get a error:
SQL.SyntaxErrorException: Unknown column 'product0_.productCategory_category'
Looking at this error, it seems it tried to read the join column name as productCategory_category instead of just category (which is the desired one)
#JoinColumn needs to go on Product class on ProductCategory field and name="categoryno"
So i've solved this thing with
#Entity
#Table(name="Products")
#Data
public class Product{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="productno")
private long ID;
#Column(name="name")
private String productName;
#ManyToOne
#JoinColumn(name="category", referencedColumnName="categoryno")
private ProductCategory category;
}
#Entity
#Table(name="Category")
#Data
public class ProductCategory{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="categoryno")
private long ID;
#Column(name="name")
private String categoryName;
#OneToMany(mappedBy="category")
private List<Product> product;
}
i have no idea why this works, but hey: magic
I've got following two tables:
Customer
id
name
Order
id
product_name
customer_id
with a 1 to 1 relation
and java entities:
#Data
public class Customer{
#Id
private Long id;
private String name;
}
#Data
public class Order{
#Id
private Long id;
#Column("id")
private Customer customer; //i want to somehow map this
private String productName;
}
and a controller
#Controller
public class MyController{
//...
#GetMapping("/")
public String getmap(Model m){
System.out.println(repository.findAll()) //prints "nullrows" due to wrong sql statement
return "mytemplate";
}
}
my current issue is, that spring is executing following sql statement:
SELECT Order.id, Order.product_name, Customer.id, Customer.name
FROM Order LEFT OUTER JOIN Customer ON Customer.id = Order.id
what i actually want is to join on Customer.id = Order.customer_id while leaving the classes as they are i.e. the customer reference needs to stay in order.
i've tried every annotation that i could find so far and have made no progress.
EDIT:
I am not allowed to use jpa/hibernate
One workaround is to do the following:
#Data
public class Customer{
#Id
private Long id;
private String name;
}
#Data
public class Order{
#Id
private Long customerId;
private Long id;
#Column("id")
private Customer customer; //i want to somehow map this
private String productName;
}
causing this to automatically join on Customer.id = Order.customer_id
This does not look like a good fix however.
You can use #OneToOne and #JoinColumn annotations for your One-to-One relationship:
#Data
public class Customer{
#Id
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "order_id", referencedColumnName = "id")
private Order order;
}
#Data
public class Order{
#Id
#Column(name = "id")
private Long id;
#Column(name = "product_name")
private String productName;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "customer_id", referencedColumnName = "id")
private Customer customer;
}
public class OrderEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="order_id")
private int orderid;
#ManyToOne
#JoinColumn(name="user_id", nullable=false)
private UserEntity user;
#OneToMany(mappedBy="ordersBid",fetch=FetchType.EAGER)
private Set<BidPriceEntity> bidOrders;
}
public class BidPriceEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#ManyToOne
#JoinColumn(name="order_Id",nullable=false)
private OrderEntity ordersBid;
#ManyToOne
#JoinColumn(name="driver_Id",nullable=false)
private UserEntity driver;
#Column(name="bid_price")
private double bidPrice;
}
public class OrderEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="order_id")
private int orderid;
#ManyToOne
#JoinColumn(name="user_id", nullable=false)
private UserEntity user;
#OneToMany(mappedBy="ordersBid",fetch=FetchType.EAGER)
private Set<BidPriceEntity> bidOrders;
}
Here are the three entities.I am trying to tansfer the data(retrieved from database) to JsonArray.it always get error :There is a cycle in the hierarchy!
how should I set the : JsonConfig (setJsonPropertyFilter) properties to get
rid of this error.
Basically there are two options for cycle - write own serializer, use #JsonIgnore. Like in your code - OrderEntity contains list of BidPriceEntities, which in turn contains reference to OrderEntity. Mark ordersBid with #JsonIgnore and it should work. At list serialization... If you don't have access to the class - try mixins.