I am currently developing a java ee application but i am having problems with the JPA.
I have two entities:
#Entitiy
public class Restaurant implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Desk> desks;
}
#Entitiy
public class Desk implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne
#JoinColumn(name = "restaurant_id")
private Restaurant restaurant;
}
And i am storing the desks with the following code:
Desk desk = new Desk();
desk.setNumber(Integer.toString(x));
desk.setRestaurant(restaurant);
em.persist(desk);
But now the strange thing is that the list of desks in the entity restaurant is empty but the restaurant value in the entity desk is correct.
The Database shema looks like that:
RESTAURANT (ID)
DESK (ID, RESTAURANT_ID)
RESTAURANT_DESK (RESTAURANT_ID, DESK_ID)
The table RESTAURANT_DESK is always empty. Why is this third table generated? And why is the list of desks in the entity restaurant empty?
For a bi-directional mapping, you need to give mappedBy attribute in the Restaurant entity to indicate the inverse relationship:
#Entity
public class Restaurant implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="restaurant")
private List<Desk> desks;
}
I found the problem. I had to add the entity desk also to the restaurant list.
Desk desk = new Desk();
desk.setNumber(Integer.toString(x));
desk.setRestaurant(restaurant);
restaurant.getDesks().add(desk);
em.persist(desk);
Related
I work with an embedded H2 database in which I use the #OneToMany relationship to relate an entity instance (product) to multiple instances of the other entities (suppliers); it's useful when I have specific suppliers for a particular product.
However now, I want to associate all the suppliers with every single product; I don't want to generate in my supplier table different supplier records for each product, instead I want to have only 5 records (5 suppliers) in my supplier table which are associated to every single product, it few words I want to achieve something like "one to all", is it possible to do it using JPA annotations?
Product entity
#Entity
public class Product {
#Id
private String productCode;
#OneToMany
#JoinColumn(name = "supplier_id", referencedColumnName = "productCode")
private List<Supplier> suppliers;
}
Supplier entity
#Entity
public class Supplier {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
private String name;
}
Unidirectional #OneToMany association:
#Entity
public class Product {
#Id
// #Column(name = "id") maybe
// #GeneratedValue maybe
private String productCode;
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) // according to your need
private List<Supplier> suppliers;
...
}
And,
#Entity
public class Supplier {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
...
}
#ManyToOne association:
#Entity
public class Product {
#Id
// #Column(name = "id") maybe
// #GeneratedValue maybe
private String productCode;
...
}
And,
#Entity
public class Supplier {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne
#JoinColumn(name = "product_id", foreignKey = #ForeignKey(name = "PRODUCT_ID_FK"))
private Product product;
private String name;
...
}
Lets say I have bidirectional one-to-many association between Parent-Child, mapped as follows:
TradingAccount.java
public class TradingAccount {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(mappedBy = "tradingAccount", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UnderlyingPerTradingAccount> underlyingPerTradingAccounts;
#Version
private Long version;
}
UnderlyingPerTradingAccount.java
public class UnderlyingPerTradingAccount {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(cascade = {CascadeType.PERSIST})
private TradingAccount tradingAccount;
private Boolean enableBuy;
private Boolean enableSell;
}
this code work, but the problem after saving or updating Trading Account I found new three trading account in the database (primary key + null in all other columns)
Im learning JPA and I have an entity class named User that has two lists of another entity, Car, but i cant get it to work with jpa.
The classes have all the getters, setters and constructors needed.
This is my User class:
#Entity
#Table(name = "Users")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(unique = true)
private String userName;
#OneToMany(i dont know what goes here as well)
private List<Car> owned;
#OneToMany( ?? )
private List<Car> rented;
This is my Car class:
#Entity
#Table(name = "Cars")
public class Car implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne ( ?? )
private User owner;
My two questions would be:
What annotations go to each #Something to make this work?
After i have all set up, how would i add a new car to an existing user and persist it as well?
Thank you!
public class Customer implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "idCustomer")
private Integer idCustomer;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "idCustomer")
private Collection<Login> loginCollection;
}
public class Login implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idLogin")
#JoinColumn(name = "idCustomer", referencedColumnName = "idCustomer")
#ManyToOne(optional = false)
private Customer idCustomer;
}
//trying to save the customer and login in the database
ArrayList<Login> logins = new ArrayList<Login>();
Login log = new Login();
log.setIdCustomer(cust);
logins.add(log);
cust.setLoginCollection(logins);
cust = custRepo.save(cust); //failed
//Login log = new Login();
//log.setUName(user);
//log.setPassword(pass);
//log.setIdCustomer(cust);
//cust = custRepo.save(cust);
//logRepository.save(log); //failed too.
I'm using spring data in my project. I have 2 model classes Customer and Login. My login class has a foreign key idCustomer in the database. When I try to save the customer without a login, it works fine but the problem is that I can't save a login object in the database.
I'm getting an error saying
Unknown column 'id_customer' in 'field list'
the jpa entities are generated.
Here is an image actual database.
Too many idCustomers in your example.
Try the code below.
I have changed a bit the annotated members #OneToMany and #ManyToOne,
following the tips established here JPA JoinColumn vs mappedBy
Also I have included idLogin in Login class. I don't know if this was a typo in your code.
public class Customer implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "idCustomer")
private Integer idCustomer;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "customer")
private Collection<Login> loginCollection;
}
public class Login implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idLogin")
private Integer idLogin;
#ManyToOne
#JoinColumn(name="idCustomer", insertable=false, updatable=false)
private Customer customer;
}
You need to you annotation
#JoinColumn
please go through these
https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/JoinColumns.html
http://docs.oracle.com/javaee/6/api/javax/persistence/JoinColumn.html
i have an Entity with following mappings:
#Entity
#Table(name = "template_product")
public class TemplateProductBean implements Serializable {
private static final long serialVersionUID = -1821696115330320798L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "product_id")
private Long productId;
// bi-directional many-to-one association to
// Template
#ManyToOne
#JoinColumn(name = "template_id")
private TemplateBean template;
The Template Bean looks as following:
#Entity
#Table(name = "template")
public class TemplateBean implements Serializable {
private static final long serialVersionUID = 3752018564161042623L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "platform_id")
private Long platformId;
#Column(name = "template_name")
private String templateName;
// bi-directional many-to-one association to
// TemplateProduct
#OneToMany(mappedBy = "template")
private List<TemplateProductBean > templateProductBean;
The Problem im facing is, im very untrained when it comes down to use the JPA Interfaces. How can i use these to get the following query:
select template
from Template template
join TemplateProductBean templateProducts
on template.templateId = templateProducts.template.templateId
where templateProducts.productId in :templateProductIdList
How can i use the JPA Interfaces( javax.persistence.criteria.Root, javax.persistence.Join etc.) to build this query as a Predicate? I'm sorry if im being unclear, i have to use this and im not used to using the JPA. Thanks
I think this should work
select t from TemplateBean t inner join t.templateProductBean tpb where tpb.productId in :templateProductIdList
More details on inner joins and HQL in general: documentation