Getting an error when doing INSERT in Spring Data JPA [duplicate] - java

This question already has an answer here:
How to fix "java.sql.SQLException: Column 'id' not found." error in Spring Boot
(1 answer)
Closed 2 years ago.
I get an
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "PRICEAFTERDISCOUNT" not found; SQL statement:
This is my Item class
package com.example.demo.model.persistence;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
#Entity
#Data
#Table(name = "item")
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#JsonProperty
private Long id;
#Column(nullable = false)
#JsonProperty
private String name;
#Column(nullable = false)
#JsonProperty
private BigDecimal price;
#Column(nullable = false)
#JsonProperty
private BigDecimal priceAfterDiscount;
#Column(nullable = false)
#JsonProperty
private String description;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Item other = (Item) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
And this is my data.sql file
insert into item (name, price, priceAfterDiscount, description) values ('Travel Card Holder', 9.25, 0, 'A holder for your travel card');
insert into item (name, price, priceAfterDiscount, description) values ('Personalised cufflinks', 45.00, 0, 'Cufflings with your initials');
insert into item (name, price, priceAfterDiscount, description) values ('Kids T-shirt', 19.95, 0, 'A T-shirt with dinosaurs')
As far as I can tell, I have added the priceAfterDiscount into my insert statement so I do not
understand where the error comes from, or why it occurs in the first place. Please help!
I have added the priceAfterDiscount field in the Item class. And annotated the same way as the rest of the fields. Also, the syntax looks correct to me

The exception means your database table item does not contain a column named PRICEAFTERDISCOUNT. Check database column name and add it over field annotation argument this way #Column(name="database_column_name", nullable = false).
data.sql statements have to contain the right column names also.

Related

composite key join columns

My table VENDORBRANCH has composite keys: "vendorCode" and "vendorBranchCode" which I have defined using the #Id annotation and using #IdClass. The field "vendorCode" is referenced as a foreign key in VENDORCRTERMS class. I'm using postgresql db.
Right now my sql query in the service implimentation looks like this but i want to include composite keys in the query:
Query<?> query = session.createQuery("from VENDORBRANCH where vendorCode = ?");
query.setParameter(0, mf01_vendorCode);
I'm very new to hibernate so tried a few options for the select query but I'm not sure if it's correct to do it this way. So, what would be the best select statement to use for a composite key??
VENDORBRANCH class:
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import com.parkson.poMain.backend.data.VENDORBRANCH.VBpk;
#SuppressWarnings("serial")
#Entity
#IdClass(VBpk.class)
public class VENDORBRANCH implements Serializable {
#Id
private String vendorCode;
#Id
private String vendorBranchCode;
//getters and setters
// inner class defined for primary key(composite keys)
public static class VBpk implements Serializable {
protected String vendorCode;
protected String vendorBranchCode;
public String getvendorCode() {
return vendorCode;
}
public void vendorCode(String vendorCode) {
this.vendorCode = vendorCode;
}
public String vendorBranchCode() {
return vendorBranchCode;
}
public void vendorBranchCode(String vendorBranchCode) {
this.vendorBranchCode = vendorBranchCode;
}
public VBpk(){}
public VBpk(String vendorCode,String vendorBranchCode){
this.vendorCode = vendorCode;
this.vendorBranchCode = vendorBranchCode;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((vendorBranchCode == null) ? 0 : vendorBranchCode.hashCode());
result = prime * result + ((vendorCode == null) ? 0 : vendorCode.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
VBpk other = (VBpk) obj;
if (vendorBranchCode == null) {
if (other.vendorBranchCode != null)
return false;
} else if (!vendorBranchCode.equals(other.vendorBranchCode))
return false;
if (vendorCode == null) {
if (other.vendorCode != null)
return false;
} else if (!vendorCode.equals(other.vendorCode))
return false;
return true;
}
}
}
My other class: VENDORCRTERMS
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#SuppressWarnings("serial")
#Entity
public class VENDORCRTERMS implements Serializable {
#Id
private String vcrId ;
//This is the foreign key referenced from **VENDORBRANCH class**
#ManyToOne
#JoinColumns( {
#JoinColumn(name="vendorcode", nullable = false),
#JoinColumn(name="vendorBranchCode", nullable = false)} )
private VENDORBRANCH vendorbranch_vendorcode = new VENDORBRANCH();
// foreign key referenced from a different class
#ManyToOne
#JoinColumn(name= "creditterms_credittermscode" , nullable = false)
private CREDITTERMS creditterms_credittermscode = new CREDITTERMS();
//getters and setters
}
VENDORBRANCH has defined a composite primary key but in VENDORCRTERMS you only use on #JoinColumn for the reference. This is how the mapping should look like in your case:
#ManyToOne
#JoinColumns( {
#JoinColumn(name="vendorCode", referencedColumnName="vendorCode"),
#JoinColumn(name="vendorBranchCode", referencedColumnName="vendorBranchCode")
} )
private VENDORBRANCH vendorbranch_vendorcode
The reason is: VENDORCRTERMS class is confused because he observed that there are two #ids in VENDORBRANCH. I have a solution for you. What if you make the vendorCode and vendorBranchCode as unique key as well as keeping only one primary key.
#Id
private String vendorCode;
I think this will satisfy your demand.

Join two tables and send as one record

Suppose, that we have such tables:
Table Users
iduser | password
Table Marks
id | iduser | mark | idtest
Table Tests
idtest | title
Query looks like this:
#GET
#Path("/{id}/marks")
#Produces(MediaType.APPLICATION_JSON)
public Object funkcja(#PathParam("id") Integer iduser) {
Query query = em.createQuery("select m,t from Marks m, Tests t where m.idusers=:iduser and m.idtest = t.idtests");
query.setParameter("iduser", id);
List<Object> results = (List<Object>)query.getResultList();
return results;
}
I have entity classes:
Marks , Users, Tests
What I should to do in order to join tables and send JSON type on web service and how to convert JSON to entity class because I would like to show in TableView.
Perhaps there are other simple ways?
Maybe map or JsonObject?
You seem to have multiple questions here; I think you need to break these down into separate questions.
For the "main" question, which is about JPA and how to join the entities, I would do that at the entity level, not at the query level. I.e. I think I would have entity classes like:
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="Tests")
public class Test {
#Id
#Column(name="idtest")
private int id ;
private String title ;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Override
public boolean equals(Object other) {
if (other instanceof Test) {
return Objects.equals(title, ((Test)other).title);
} else return false ;
}
#Override
public int hashCode() {
return Objects.hash(title);
}
}
and then the Mark entity can use a #ManyToOne annotation to reference the actual Test object (not its id):
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="Marks")
public class Mark {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id ;
#ManyToOne
#JoinColumn(name="idtest")
private Test test ;
// You probably don't want a reference to User here, as the User class
// encapsulates the password, which you don't want to throw back and
// forward across the network unnecessarily. But if the User class
// instead had a user name etc you wanted, you could use the same
// #ManyToOne technique to reference a User object here if you needed.
#Column(name="iduser")
private int userId ;
private int mark ;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public Test getTest() {
return test;
}
public void setTest(Test test) {
this.test = test;
}
public int getMark() {
return mark;
}
public void setMark(int mark) {
this.mark = mark;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Mark) {
Mark other = (Mark)obj ;
return Objects.equals(userId, other.userId)
&& Objects.equals(test, other.test)
&& mark == other.mark ;
} else return false ;
}
#Override
public int hashCode() {
return Objects.hash(userId, test, mark);
}
}
Now your query looks like
TypedQuery<Mark> query = em.createQuery("select m from Mark m where m.userId=:userid");
query.setParameter("userid", iduser);
List<Mark> results = query.getResultList();
and the Mark instances in the list already have all the data you need:
for (Mark mark : results) {
System.out.println(mark.getTest().getTitle() + ": " + mark.getMark());
}
For the remaining questions:
Assuming you have a server set up with a JAX-RS implementation (e.g. Jersey) the code snippet you showed (modified with the new query) should generate JSON output. (You can use a developer tool such as Firefox REST client to view the JSON output by specifying the appropriate URL and request headers, and viewing the response.)
On the client (JavaFX) side you can use Jersey's client library (or maybe Apache HttpComponent library) to create the web requests easily, and a library such as GSON or Jackson for mapping the JSON content you get back to a Java object for display in the TableView.
I recommend trying this and asking specific questions about the remaining pieces if you get stuck.

Jersey incorrectly parsing json long

I'm using jersey to create a json/xml REST api. But I've encountered some strange behavior in Moxy.
It seems to cut off a java long and round the value up when it is larger than a certain value.
The primary key I use for the entity in question is: 871687120000007010, but if I query my api to test, the following happens:
http://i.stack.imgur.com/QbExD.png
Note that the image shows the "EAN" (the primary key) has been cut off.
After doing some testing with it I found out the following:
Using 9223372036854775807 as primary key (max value for 64bit signed integer)
Yields: 9223372036854776000 after it has been parsed by moxy. This is higher than a 64bit signed int can be.
But putting in 9223372036854774807
Yields 9223372036854775000
It seems to round high values up with 1000 precision.
Does anyone have an idea what is going on here ?
Model class:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "CONNECTION")
#XmlRootElement
public class P4Connection {
#XmlElement
#Column(name = "SENDER", nullable = false)
private long sender;
#XmlElement
#Column(name = "RECEIVER", nullable = false)
private long receiver;
#Id
#XmlElement(type = Long.class)
#Column(name = "ID", nullable = false)
private long ean;
#XmlElement
#Column(name = "LAST_COLLECT")
private Date lastCollect;
#ManyToMany
private Set<Request> REQUEST;
public P4Connection() {
REQUEST = new HashSet<>();
}
#XmlTransient
public long getSender() {
return sender;
}
public void setSender(long sender) {
this.sender = sender;
}
#XmlTransient
public long getReceiver() {
return receiver;
}
public void setReceiver(long receiver) {
this.receiver = receiver;
}
#XmlTransient
public long getEan() {
return ean;
}
public void setEan(long id) {
this.ean = id;
}
#XmlTransient
public Date getLastCollect() {
return lastCollect;
}
public void setLastCollect(Date lastCollect) {
this.lastCollect = lastCollect;
}
public Set<Request> getRequests() {
return REQUEST;
}
}
The API method:
#GET
#Path("/{ean}")
#Produces(MediaType.APPLICATION_JSON)
public P4Connection getConnection(#PathParam("ean") String ean,
#Context UriInfo uriInfo) throws AppException {
long eancode = parseEAN(ean, uriInfo);
Session session = Database.getInstance().getSession();
Query query = session.createQuery("from P4Connection where ean = ?");
query.setLong(0, eancode);
List connections = query.list();
session.close();
if (connections.size() != 1)
throw new AppException(ErrorCode.NOT_FOUND, uriInfo);
System.out.println(((P4Connection) connections.get(0)).getEan());
return (P4Connection) connections.get(0);
}
This doesn't happen when I render it as XML by changing the #Produces annotation
Turns out the plugin I was using in my browser was incorrectly displaying the long value

why JPA Foriegn Key Related (#ManyToOne )Child objects are getting detached on persisting the parent object

My Child objects are getting detached once after the parent object is persisted. on returning the parent object to view ,my child objects are null. To resolve this I'm fetching the object again from database to process in the view.
//Pseudocode
Parent Entity
class Donor{
#ManyToOne(fetch = FetchType.EAGER)
private PreferredLanguage preferredLanguage;
}
Child Entity
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package model.preferredlanguage;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
*
* #author srikanth
*/
#Entity
public class PreferredLanguage {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false, insertable=false, updatable=false)
private Long id;
#Column(length=20)
private String preferredLanguage;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPreferredLanguage() {
return preferredLanguage;
}
public void setPreferredLanguage(String preferredLanguage) {
this.preferredLanguage = preferredLanguage;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof PreferredLanguage)) {
return false;
}
PreferredLanguage other = (PreferredLanguage) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
}
Crntroller AddDonor Method
savedDonor = donorRepository.addDonor(donor);
Repository Method
public Donor addDonor(Donor donor) {
updateDonorAutomaticFields(donor);
em.persist(donor);
em.flush();
return donor;
}
Can you please provide code snippets,
My guess, your child objects may be of FetchType FetchType.LAZY

In class without a property called "type" I get org.hibernate.PropertyNotFoundException: Could not find a setter for property type in class

Using JPA, and Hibernate as the provideer, I have a class defined like:
#Entity
#Table(name="partyrole")
public class PartyRole extends BaseDateRangeModel {
private static final long serialVersionUID = 1L;
private Party roleFor;
public void setRoleFor(Party roleFor) {
this.roleFor = roleFor;
}
#ManyToOne
public Party getRoleFor() {
return roleFor;
}
}
And I get the error in title of the question. I've tried adding public void setType(Object type) but that doesn't work either. The persistence.xml file is normal.
There are two classes that reference this one, but neither of them attempts to invoke setType either. I'd apprecaite any help!!!!
This happens at deployment time. The stack trace is at the bottom.
The Parent Class:
package com.nsfw.bmp.common.jpa;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotNull;
/**
* Several models are date range sensitive, this base class provides that basic
* functionality.
*
* #author jim
*
*/
#MappedSuperclass
public abstract class BaseDateRangeModel extends BasePersistentModel {
private static final long serialVersionUID = 1L;
private Date from;
private Date thru;
/**
* Determines if a model is active. A model is active if now is after or
* equal to from , and thru is either null, or after now, or equal to now.
*/
#Transient
public boolean isActive() {
Date now = new Date();
boolean afterFrom = from.before(now) || from.equals(now);
boolean beforeThru = thru == null || thru.after(now)
|| thru.equals(now);
return afterFrom && beforeThru;
}
#AssertTrue(message = "Dates are not valid the thru date must be empty, or after the fromdate.")
public boolean areDatesValid() {
if (thru == null) {
return true;
} else {
return thru.after(from);
}
}
#Temporal(TemporalType.TIMESTAMP)
#NotNull
#Column(name = "fromDate")
public Date getFrom() {
return from;
}
public void setFrom(Date from) {
this.from = from;
}
#Temporal(TemporalType.TIMESTAMP)
public Date getThru() {
return thru;
}
public void setThru(Date thru) {
this.thru = thru;
}
}
Its parent:
package com.nsfw.bmp.common.jpa;
import java.io.Serializable;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
#MappedSuperclass
public abstract class BasePersistentModel implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
protected Long id;
protected Long version = 0l;
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BasePersistentModel other = (BasePersistentModel) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
#Id
#GeneratedValue
public Long getId() {
return id;
}
#Version
public Long getVersion() {
return version;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
public void setId(Long id) {
this.id = id;
}
public void setVersion(Long version) {
this.version = version;
}
}
The Party class is fairly large, with a lot of mappings. This is the one asked for:
/**
* #return the actingAs
*/
#OneToMany(mappedBy="roleFor", targetEntity=com.nsfw.bmp.party.entity.association.PartyRole.class)
#OrderBy("from")
public List<PartyRole> getActingAs() {
return actingAs;
}
Here's the stack trace:
Caused by: org.hibernate.PropertyNotFoundException: Could not find a setter for property type in class com.nsfw.bmp.party.entity.association.PartyRole
at org.hibernate.property.BasicPropertyAccessor.createSetter(BasicPropertyAccessor.java:240)
at org.hibernate.property.BasicPropertyAccessor.getSetter(BasicPropertyAccessor.java:233)
at org.hibernate.mapping.Property.getSetter(Property.java:299)
at org.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertySetter(PojoEntityTuplizer.java:272)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:149)
at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:76)
at org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping.<init>(EntityEntityModeToTuplizerMapping.java:80)
at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:325)
at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:457)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:131)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:84)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:261)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
Can you post your party class? I have a suspicion that this has to do with your manytoone mapping. Is there a type column in the partyRole table?
You problem might be linked to the BaseDateRangeModel class, because PartyRole extends it.
can you show us that class?
If you're getting this during startup, it means you have a class somewhere referencing PartyRole via inverse relationship, e.g. something along the lines of
#OneToMany(targetEntity=PartyRole.class, inverse=true")
in some other entity. Set hibernate logging level to DEBUG - it should help you to narrow the problem.

Categories