In Spring mvc How to add add set values to mysql - java

My goal :
In Spring MVC I have to save mobile phone contact list into database.
example:
phone1 sonia 2554654 work
2554654 home
multiple phone_number with multiple phone_Number type
contacts table
id,
contact_name
phone_number
phone_type
in my java class I have
public class ContactMobile {
private String type;
private String number;
public ContactMobile() {
}
public ContactMobile(String type, String number) {
super();
this.type = type;
this.number = number;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
and here I use SET for phone number and type
#Entity
#Table(name = "_contact")
public class MobileContact {
private String id;
private String fullname;
private Set<ContactMobile> mobileNumbers;
public MobileContact(String fullname, Set<ContactMobile> mobileNumbers) {
super();
this.fullname = fullname;
this.mobileNumbers = mobileNumbers;
}
#Id
#Column(name = "Id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "fullname")
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public Set<ContactMobile> getMobileNumbers() {
return mobileNumbers;
}
public void setMobileNumbers(Set<ContactMobile> mobileNumbers) {
this.mobileNumbers = mobileNumbers;
}
public MobileContact() {
super();
}
}
I am using hibernate to store data..
my question is in my MobileContact class in
public Set<ContactMobile> getMobileNumbers() {
return mobileNumbers;
}
what annotation I have to use here to save multiple phonenumbers?

The MobileContact entity has many ContactMobile, it is a OneToMany relation. In your ContactMobile table, you should has a field for the id of MobileContact, like mobile_contact_id, and set the join column on that field as below in your ContactMobile:
#OneToMany(fetch = FetchType.LEZY)
#JoinColumn(name = "mobile_contact_id")
private Set<ContactMobile> mobileNumbers;
You can get the detail about the relation in this.

You can use the Embeddables (instead of Entities) for very simple value objects like MobileContact (then they do not need an ID, and the are no just simple value objects without own identity)
#Embeddable
public class ContactMobile {...
//implement an equals and hashcode method!
}
public class MobileContact {
...
#ElementCollection
private Set<ContactMobile> mobileNumbers;
...
}
#See Java Persistence/ElementCollection

Related

Spring MVC model binding not working for non public members

I have class Product with members like Name, Description... which are private, and I have public getter and setter methods. I tried to make Spring Boot MVC REST controller with POST method but it seams that what I am sending is not bind to model. This is JSON I'm sending to controller:
{
"Name": "proizvod7",
"Description": "neki opis2",
"CategoryId":1,
"Price":"15"
}
This is my code:
#RequestMapping(value = {"","/"},method = RequestMethod.POST,consumes = "application/json",produces="application/json")
public ResponseEntity PostProduct(#RequestBody #Valid Product p, BindingResult result){
if (!result.hasErrors()) {
return new ResponseEntity<>(service.insert(p), HttpStatus.CREATED);
} else
return new ResponseEntity(HttpStatus.BAD_REQUEST);
}
}
I figured that out when I created new class ProductDto which has public members Name, Description...
This is working version:
#RequestMapping(value = {"","/"},method = RequestMethod.POST,consumes = "application/json",produces="application/json")
public ResponseEntity PostProduct(#RequestBody #Valid ProductDto productDto, BindingResult result) {
if (!result.hasErrors()) {
Product p = new Product(productDto.Name, productDto.Price, productDto.Description, productDto.CategoryId);
return new ResponseEntity<>(service.insert(p), HttpStatus.CREATED);
} else {
return new ResponseEntity(HttpStatus.BAD_REQUEST);
}
}
However project is simple enough so I don't want to introduce DTO classes, but I would like to have private members inside my initial Product class with public getters and setters. Is it possible?
EDIT:
Here is Product class:
#Data
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "products")
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
public Product(#NotNull String name, BigDecimal price, String description, Long category_id) {
Name = name;
Price = price;
Description = description;
Category_id = category_id;
}
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public BigDecimal getPrice() {
return Price;
}
public void setPrice(BigDecimal price) {
Price = price;
}
public String getDescription() {
return Description;
}
public void setDescription(String description) {
Description = description;
}
#NotNull
private String Name;
private BigDecimal Price;
private String Description;
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public Long getCategory_id() {
return Category_id;
}
public void setCategory_id(Long category_id) {
Category_id = category_id;
}
#Column(name = "category_id",nullable = true)
private Long Category_id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="category_id",updatable = false,insertable = false)
private Category category;
}
It seems your field names are breaking the deserializing logic. I do not know why are you trying to use those uppercase field names, but the problem is that when there is a setter for Name field, setName(), Jackson thinks this maps to a field name, not Name, hence the issue.
You should use #JsonProperty()
#JsonProperty("Name")
private String Name;
#JsonProperty("Price")
private BigDecimal Price;
#JsonProperty("Description")
private String Description;
#JsonProperty("categoryId")
#Column(name = "category_id", nullable = true)
private Long Category_id;
Also with #Data annotation from Lombok, you do not need to write all those getters/setters, they are already generated for you.
You can use #JsonSetter at the public setters... something like this
public class MyBean {
private String name;
#JsonSetter("name")
public void setTheName(String name) {
this.name = name;
}
}
You can check more examples here:
https://www.baeldung.com/jackson-annotations
#JsonSetter ref here https://fasterxml.github.io/jackson-annotations/javadoc/2.0.0/com/fasterxml/jackson/annotation/JsonSetter.html

Eclipse 'generate entities from tables' and 'many to one' relation

i am developing a simple Java EE application, that uses database. It has two tables (Admin and Session signature) connected with many to one relation.
When i used eclipse to generate entities from tables, my attribute that links both tables was generated like this:
//bi-directional many-to-one association to Admin
#ManyToOne
#JoinColumn(name="owner")
private Admin admin;
Problem is, my owner attribute is Integer in database, and it has been created as Admin type.
Now when i want to pass some Integer variable to input it to database i get error:
The method setAdmin(Admin) in the type Signaturesession is not applicable for arguments (int).
Or when i want to cast it to (Admin) like this (taking it from session):
(Admin)session.getAttribute("adminId")
I get Jboss Error:
javax.servlet.ServletException: java.lang.ClassCastException: java.lang.Integer cannot be cast to com.podpisy.entities.Admin
javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
secure.SecurityCheckFilter.doFilter(SecurityCheckFilter.java:100)
I am sure that this can be done easy, but i'm just really bad using Java.
Thanks for any help.
EDIT:
My Admin.java class:
package com.podpisy.entities;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
#Entity
#Table(name="admins")
#NamedQuery(name="Admin.findAll", query="SELECT a FROM Admin a")
public class Admin implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private int id;
private String login;
private String password;
//bi-directional many-to-one association to Signature
#OneToMany(mappedBy="admin")
private List<Signature> signatures;
//bi-directional many-to-one association to Signaturesession
#OneToMany(mappedBy="admin")
private List<Signaturesession> signaturesessions;
public Admin() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getLogin() {
return this.login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public List<Signature> getSignatures() {
return this.signatures;
}
public void setSignatures(List<Signature> signatures) {
this.signatures = signatures;
}
public Signature addSignature(Signature signature) {
getSignatures().add(signature);
signature.setAdmin(this);
return signature;
}
public Signature removeSignature(Signature signature) {
getSignatures().remove(signature);
signature.setAdmin(null);
return signature;
}
public List<Signaturesession> getSignaturesessions() {
return this.signaturesessions;
}
public void setSignaturesessions(List<Signaturesession> signaturesessions) {
this.signaturesessions = signaturesessions;
}
public Signaturesession addSignaturesession(Signaturesession signaturesession) {
getSignaturesessions().add(signaturesession);
signaturesession.setAdmin(this);
return signaturesession;
}
public Signaturesession removeSignaturesession(Signaturesession signaturesession) {
getSignaturesessions().remove(signaturesession);
signaturesession.setAdmin(null);
return signaturesession;
}
}
My Signaturesession.class:
package com.podpisy.entities;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the signaturesession database table.
*
*/
#Entity
#NamedQuery(name="Signaturesession.findAll", query="SELECT s FROM Signaturesession s")
public class Signaturesession implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private int id;
private String device;
private String name;
private int signatures;
private int time;
private String type;
private int users;
//bi-directional many-to-one association to Admin
#ManyToOne
#JoinColumn(name="owner")
private Admin admin;
public Signaturesession() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getDevice() {
return this.device;
}
public void setDevice(String device) {
this.device = device;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getSignatures() {
return this.signatures;
}
public void setSignatures(int signatures) {
this.signatures = signatures;
}
public int getTime() {
return this.time;
}
public void setTime(int time) {
this.time = time;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public int getUsers() {
return this.users;
}
public void setUsers(int users) {
this.users = users;
}
public Admin getAdmin() {
return this.admin;
}
public void setAdmin(Admin admin) {
this.admin = admin;
}
}
You should pass an Admin object which surely has an int id field.
So you've to make something like this
Admin myAdmin=new Admin(id,.. other properties);
mySignaturesession.setAdmin(myAdmin);
EDIT
Above is valid if you want to associate and Admin to your SignatureSession object. Instead if you have an Admin ojbect in Session you just have to execute
Admin anAdmin=(Admin)session.getAttibute("adminId");
Admin myAdmin=new Admin(id,.. other properties);
or
Admin myAdmin=new Admin();
myAdmin.setId(anId);
But, i repeat, it depends from what you have in the Session and which objects you handle.
And, as you look to be using JPA, dont forget to do something like em.persist or em.merge on your objects.
Maybe you should get a little deeper on how JPA works.

Caused by: java.sql.SQLSyntaxErrorException: ORA-01722: invalid number in JPA HIBERNATE HQL

Having this class
#Entity
public class PriorityAreaKeyword {
public enum PriorityAreaKey {
ALL ("ALL", "ALL DEVICES"),
IOS ("IOS", "IOS"),
ANDROID ("ANDROID","ANDROID");
private final String name;
private final String id;
private PriorityAreaKey(String name, String id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
}
#Id
private Long id;
#Column(name = "key")
#Enumerated(EnumType.STRING)
private PriorityAreaKey key;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public PriorityAreaKey getKey() {
return key;
}
public void setKey(PriorityAreaKey key) {
this.key = key;
}
public List<PriorityArea> getPriorityAreas() {
return priorityAreas;
}
public void setPriorityAreas(List<PriorityArea> priorityAreas) {
this.priorityAreas = priorityAreas;
}
}
I have in the DAO this method that is working fine:
#Override
#SuppressWarnings("unchecked")
public Set<PriorityArea> findPriorityAreas(PriorityAreaKey key) {
String jpql = "from PriorityAreaKeyword as pak where pak.key = :key";
Query query = entityManager.createQuery(jpql);
query.setParameter("key", key);
List<PriorityArea> priorityAreas = query.getResultList();
return new HashSet<PriorityArea>(priorityAreas);
}
I created a view like this v_report_beneficiary_list (id, email, priority_area_key)
/**
*
*/
#Entity
#Table(name = "v_report_beneficiary_list")
public class ReportBeneficiaryItem {
private Long id;
private String email;
private PriorityAreaKey priorityAreaKey;
/**
* #return the id
*/
#Id
public Long getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
#Column(name = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "priority_area_key")
public PriorityAreaKey getPriorityAreaKey() {
return priorityAreaKey;
}
public void setPriorityAreaKey(PriorityAreaKey priorityAreaKey) {
this.priorityAreaKey = priorityAreaKey;
}
In the DAO I've created another method like this:
#Su
ppressWarnings("unchecked")
#Override
public List<ReportBeneficiaryItem> findReportProposalXBeneficiary(ProposalExportFilter filter) {
// Create basic query
String jpql = "from " + ReportBeneficiaryItem.class.getName() + " b where b.priorityAreaKey = :key ";
// Create and execute jpa query
Query query = createQuery(jpql);
query.setParameter("key", filter.getPriorityAreaKey());
return query.getResultList();
}
That throws me a throws me an Exception Caused By: java.sql.SQLSyntaxErrorException: ORA-01722: invalid number
You are missing #Enumerated(EnumType.STRING) on ReportBeneficiaryItem#getPriorityAreaKey() as you have on PriorityAreaKeyword#key, so it's expecting numbers (enum index) in the database for that field, but finds strings
#Column(name = "priority_area_key")
#Enumerated(EnumType.STRING)
public PriorityAreaKey getPriorityAreaKey() {
return priorityAreaKey;
}

Retrieve data using hsql - relation many to one

I define the following entities :BaseEntity , magasin and article :
#Entity(name = "magasin")
#Table(name = "magasin")
public class Magasin extends BaseEntity {
private static final long serialVersionUID = 1L;
#Basic
#Size(min=5, max=100, message="The name must be between {min} and {max} characters")
private String name;
#OneToMany(cascade=CascadeType.ALL, mappedBy="magasin")
#Valid
private Set<Article> article;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Article> getArticle() {
return article;
}
public void setArticle(Set<Article> article) {
this.article = article;
}
}
#Entity(name="article")
#Table(name="article")
public class Article extends BaseEntity {
private static final long serialVersionUID = 1L;
#ManyToOne
private Magasin magasin;
#Basic
#Size(min=5, max=100, message="The name must be between {min} and {max} characters")
private String name;
#Basic
private float price;
public Magasin getMagasin() {
return magasin;
}
public void setMagasin(Magasin magasin) {
this.magasin = magasin;
}
public String getName() {
return name;
}
public void setName(String nom) {
this.name = nom;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
#MappedSuperclass
public class BaseEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public boolean isNew() {
return (this.id == null);
}
}
How can create a hql query in order to retrieve all Article for a magasin selected ?
I try this
#Override
public List<Article> findArticle(Magasin magasin) {
String query = "From Article m where m.magasin.id = "+magasin.getId();
System.out.print(query);
Session session = getSessionFactory().getCurrentSession();
if((session.createQuery(query).list()!=null) && (session.createQuery(query).list().size()!=0))
return (List<Article>) session.createQuery(query).list();
else
return null;
}
But it returns nothing , always null .How can I resolve it ?
I don't know the type of your magasin id so adapt the code below.
First get the Magasin instance for the id:
Magasin mag = (Magasin)session.get(Magasin.class, id);
Next you can access the articles for the magasin mag via accessor
Set<Article> articles = mag.getArticle();
Try this:
"Select * From Article,Mgasin where Article.mgasin.id = "+magasin.getId();

hibernate gives two rows the same instead of two distinct rows

I have a user dao
#Entity
#Table(name="EBIGUSERTIM")
public class EbigUser {
private String id;
private Integer source;
private String entryscheme;
private String fullName;
private String email;
private Long flags;
private String status;
private String createdBy;
private Date createdStamp;
private String modifiedBy;
private Date modifiedStamp;
#Id
#Column(name="ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Id
#Column(name="SOURCE")
public Integer getSource() {
return source;
}
public void setSource(Integer source) {
this.source = source;
}
#Column(name="ENTRYSCHEME")
public String getEntryscheme() {
return entryscheme;
}
public void setEntryscheme(String entryscheme) {
this.entryscheme = entryscheme;
}
#Column(name="FULLNAME")
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
#Column(name="EMAIL")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name="FLAGS")
public Long getFlags() {
return flags;
}
public void setFlags(Long flags) {
this.flags = flags;
}
#Column(name="STATUS")
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
#Column(name="CREATEDBY")
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
#Column(name="CREATEDSTAMP")
public Date getCreatedStamp() {
return createdStamp;
}
public void setCreatedStamp(Date createdStamp) {
this.createdStamp = createdStamp;
}
#Column(name="MODIFIEDBY")
public String getModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}
#Column(name="MODIFIEDSTAMP")
public Date getModifiedStamp() {
return modifiedStamp;
}
public void setModifiedStamp(Date modifiedStamp) {
this.modifiedStamp = modifiedStamp;
}
i am selecting 2 rows out of the db. The sql works
select * from ebigusertim where id='blah'
It returns 2 distinct rows. When i query the data using hibernate, it appears that the object memory is not being allocated for each entry in the list. Thus, i get 2 entries in the list with the same object.
Criteria userCriteria = session.createCriteria(EbigUser.class);
userCriteria.add(Restrictions.eq("id", id));
userlist = userCriteria.list();
Why are you defining two id columns(both id and source are mapped with annotation #Id)?
#Id
#Column(name="ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Id
#Column(name="SOURCE")
public Integer getSource() {
return source;
}
Please remove one if it is by mistake. If both together make composite key, map them accordingly e.g.
#Embeddable
public class UserPK implements Serializable {
#Column(name = "ID", nullable = false)
private String id;
#Column(name = "SOURCE", nullable = false)
private Integer source;
.....
.....
}
Use this new class in you original class as Id as below:
#EmbeddedId
private UserPK userPK;
Hope this helps.

Categories