JPA how to update existing object data without exception? [closed] - java

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I try to update existing data rows in database but i get that exception:
[EL Warning]: 2012-10-24 20:02:27.798--UnitOfWork(22664464)--Exception [EclipseLink-4002] (Eclipse Persistence Services -
2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '20-http://www.vilpra.lt/products/Foto/Aremikas/Katilas_zvake_big' for key 'PRIMARY' Error Code: 1062 Call: INSERT INTO x_links_media (image, link_id) VALUES (?, ?) bind => [2 parameters bound] Query: InsertObjectQuery(database.entity.XLinksMedia[ xLinksMediaPK=database.entity.XLinksMediaPK[ linkId=20, image=http://www.link.lt/products.jpg ] ])
The main object class is look like code below. There is some variables with relation OneToMany.
package database.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
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.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#Table(name = "x_parser_links")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "XParserLinks.findAll", query = "SELECT x FROM XParserLinks x"),
#NamedQuery(name = "XParserLinks.findByLinkId", query = "SELECT x FROM XParserLinks x WHERE x.linkId = :linkId"),
#NamedQuery(name = "XParserLinks.findByPageId", query = "SELECT x FROM XParserLinks x WHERE x.pageId = :pageId"),
#NamedQuery(name = "XParserLinks.findByLink", query = "SELECT x FROM XParserLinks x WHERE x.link = :link"),
#NamedQuery(name = "XParserLinks.findByLevel", query = "SELECT x FROM XParserLinks x WHERE x.level = :level"),
#NamedQuery(name = "XParserLinks.findByLinkType", query = "SELECT x FROM XParserLinks x WHERE x.linkType = :linkType"),
#NamedQuery(name = "XParserLinks.findByCreateDate", query = "SELECT x FROM XParserLinks x WHERE x.createDate = :createDate"),
#NamedQuery(name = "XParserLinks.findByDelDate", query = "SELECT x FROM XParserLinks x WHERE x.delDate = :delDate")})
public class XParserLinks implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "link_id")
private Integer linkId;
#Column(name = "page_id")
private Integer pageId;
#Column(name = "link")
private String link;
#Column(name = "level")
private Integer level;
#Column(name = "link_type")
private Short linkType;
#Column(name = "create_date")
#Temporal(TemporalType.TIMESTAMP)
private Date createDate;
#Column(name = "del_date")
#Temporal(TemporalType.TIMESTAMP)
private Date delDate;
#JoinColumn(name = "tev_link_id")
#OneToOne(cascade = CascadeType.ALL)
private XParserLinks tevas;
#OneToMany(mappedBy = "xParserLink", targetEntity = XLinksMedia.class, cascade = CascadeType.ALL)
private List<XLinksMedia> fotos;
#OneToMany(mappedBy = "xParserLink", targetEntity = XLinksVarchar.class, cascade = CascadeType.ALL)
private List<XLinksVarchar> atributes;
public XParserLinks() {
}
public XParserLinks(Integer linkId) {
this.linkId = linkId;
}
public Integer getLinkId() {
return linkId;
}
public void setLinkId(Integer linkId) {
this.linkId = linkId;
}
public Integer getPageId() {
return pageId;
}
public void setPageId(Integer pageId) {
this.pageId = pageId;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
public Short getLinkType() {
return linkType;
}
public void setLinkType(Short linkType) {
this.linkType = linkType;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getDelDate() {
return delDate;
}
public void setDelDate(Date delDate) {
this.delDate = delDate;
}
public XParserLinks getTevas() {
return tevas;
}
public void setTevas(XParserLinks tevas) {
this.tevas = tevas;
}
public List<XLinksMedia> getFotos() {
return fotos;
}
public void setFotos(List<XLinksMedia> fotos) {
this.fotos = fotos;
}
public List<XLinksVarchar> getAtributes() {
return atributes;
}
public void setAtributes(List<XLinksVarchar> atributes) {
this.atributes = atributes;
}
#Override
public int hashCode() {
int hash = 0;
hash += (linkId != null ? linkId.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 XParserLinks)) {
return false;
}
XParserLinks other = (XParserLinks) object;
if ((this.linkId == null && other.linkId != null) || (this.linkId != null && !this.linkId.equals(other.linkId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "database.entity.XParserLinks[ linkId=" + linkId + " ]";
}
}
And here is code where I want to proceed data. XParserLinks object is the man object like code above. In this example I check if object do not have his primary key LinkId then create new object with persist, but else just update object and his values, but I get exception like I mean before when I want to update existing object.
XParserLinks e = entry.getValue();
if (e.getLinkId() == null) {
try {
TarpineManager.startTransaction();
TarpineManager.persist(e);
TarpineManager.commitTransaction();
} catch (Exception ex) {
ex.printStackTrace();
if (TarpineManager.getInstance().getTransaction().isActive()) {
TarpineManager.rollbackTransaction();
}
}
} else {
try {
TarpineManager.startTransaction();
TarpineManager.commitTransaction();
} catch (Exception ex) {
ex.printStackTrace();
if (TarpineManager.getInstance().getTransaction().isActive()) {
TarpineManager.rollbackTransaction();
}
}
}

Are you, by any chance, creating your entity and setting its Id by force? I see your class has a setLinkId(Integer linkId) method on it.
First of all, you should be using merge instead of persist. Now, whit this in mind, the exception is also being thrown by the merge method because JPA can't define if the entity you want to persist is a new one or it's a previosuly fetched one, because the states in the lifecycle aren't the same.
If you create an object and set its id, that entity has the state new, but if you fetched the entity before it should have a detached state. When merged, a detached entity will be correctly updated but a new entity will be persisted and, since the id is taken, the exception is thrown.
You have the entity's ID, so you better fetch them before, update the object and then merge them.

Related

Java, Swing - Jtable row remain after delete

I have a JTable that displays data from mysql, the code below is works (can insert, update, delete) But if I delete a row and create another with the same id, the previous data in the row (before I delete it) appears instead of new data.
code for insert and delete
private void simpanBtnActionPerformed(java.awt.event.ActionEvent evt) {
String hantaranID = hantaranIDText.getText();
String namaLengkap = namaLengkapET.getText();
String alamat = jTextArea1.getText();
String hp = noHp.getText();
Date pengambilan = jXDatePicker1.getDate();
Date pengembalian = jXDatePicker2.getDate();
if (hantaranID.isEmpty()){
JOptionPane.showMessageDialog(null, "Hantaran ID tidak boleh kosong.");
} else if (namaLengkap.isEmpty()){
JOptionPane.showMessageDialog(null, "Nama lengkap tidak boleh kosong.");
} else if (alamat.isEmpty()) {
JOptionPane.showMessageDialog(null, "Alamat tidak boleh kosong.");
} else if (hp.isEmpty()){
JOptionPane.showMessageDialog(null, "Nomor Hand Phone tidak boleh kosong.");
} else if (pengambilan != null && pengembalian != null){
try {
DateFormat sysDate = new SimpleDateFormat("yyyy/MM/dd");
String tglPengambilan = sysDate.format(jXDatePicker1.getDate()).toString();
String tglPengembalian = sysDate.format(jXDatePicker2.getDate()).toString();
Connection conn = MyDBConnection.getConnection();
String insert = "insert into hantaran (hantaran_id, nama_lengkap, alamat, no_hp, tgl_pengambilan, tgl_pengembalian)"
+ "values (?, ?, ? , ? , ?, ?)";
PreparedStatement insertHantaran = conn.prepareStatement(insert, Statement.RETURN_GENERATED_KEYS);
insertHantaran.setString(1, hantaranID);
insertHantaran.setString(2, namaLengkap);
insertHantaran.setString(3, alamat);
insertHantaran.setString(4, hp);
insertHantaran.setString(5, tglPengambilan);
insertHantaran.setString(6, tglPengembalian);
insertHantaran.executeUpdate();
hantaranTabel.revalidate();
hantaranList.clear();
hantaranList.addAll( hantaranQuery.getResultList());
hantaranIDText.setText("");
namaLengkapET.setText("");
jTextArea1.setText("");
noHp.setText("");
jXDatePicker1.setDate(null);
jXDatePicker2.setDate(null);
} catch (Exception e) {
e.printStackTrace();
}
} else {
JOptionPane.showMessageDialog(null, "Tanggal Pengambilan dan Pengembalian tidak boleh kosong.");
}
// TODO add your handling code here:
}
private void hapusBtnActionPerformed(java.awt.event.ActionEvent evt) {
String id = hantaranIDText.getText();
Object[] options = { "YA", "Tidak" };
int choice = JOptionPane.showOptionDialog(null,
"Hapus data ini??",
"Hapus..!",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);
if (choice == JOptionPane.YES_OPTION){
try {
Connection conn = MyDBConnection.getConnection();
String reqq = "DELETE FROM hantaran WHERE hantaran_id = ?";
PreparedStatement delete = conn.prepareStatement(reqq);
delete.setString(1, id);
delete.executeUpdate();
hantaranTabel.revalidate();
hantaranList.clear();
hantaranList.addAll( hantaranQuery.getResultList());
editBtn.setText("EDIT");
hantaranIDText.setText("");
namaLengkapET.setText("");
jTextArea1.setText("");
noHp.setText("");
jXDatePicker1.setDate(null);
jXDatePicker2.setDate(null);
hapusBtn.setEnabled(false);
simpanBtn.setEnabled(true);
} catch (Exception ex) {
Logger.getLogger(HennaPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
my class
package aplikasi_mahar;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
/**
*
* #author User
*/
#Entity
#Table(name = "hantaran", catalog = "mahardb", schema = "")
#NamedQueries({
#NamedQuery(name = "Hantaran.findAll", query = "SELECT h FROM Hantaran h"),
#NamedQuery(name = "Hantaran.findByHantaranId", query = "SELECT h FROM Hantaran h WHERE h.hantaranId = :hantaranId"),
#NamedQuery(name = "Hantaran.findByNamaLengkap", query = "SELECT h FROM Hantaran h WHERE h.namaLengkap = :namaLengkap"),
#NamedQuery(name = "Hantaran.findByAlamat", query = "SELECT h FROM Hantaran h WHERE h.alamat = :alamat"),
#NamedQuery(name = "Hantaran.findByNoHp", query = "SELECT h FROM Hantaran h WHERE h.noHp = :noHp"),
#NamedQuery(name = "Hantaran.findByTglPengambilan", query = "SELECT h FROM Hantaran h WHERE h.tglPengambilan = :tglPengambilan"),
#NamedQuery(name = "Hantaran.findByTglPengembalian", query = "SELECT h FROM Hantaran h WHERE h.tglPengembalian = :tglPengembalian")})
public class Hantaran implements Serializable {
#Transient
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "hantaran_id")
private Integer hantaranId;
#Basic(optional = false)
#Column(name = "nama_lengkap")
private String namaLengkap;
#Basic(optional = false)
#Column(name = "alamat")
private String alamat;
#Basic(optional = false)
#Column(name = "no_hp")
private String noHp;
#Basic(optional = false)
#Column(name = "tgl_pengambilan")
#Temporal(TemporalType.DATE)
private Date tglPengambilan;
#Basic(optional = false)
#Column(name = "tgl_pengembalian")
#Temporal(TemporalType.DATE)
private Date tglPengembalian;
public Hantaran() {
}
public Hantaran(Integer hantaranId) {
this.hantaranId = hantaranId;
}
public Hantaran(Integer hantaranId, String namaLengkap, String alamat, String noHp, Date tglPengambilan, Date tglPengembalian) {
this.hantaranId = hantaranId;
this.namaLengkap = namaLengkap;
this.alamat = alamat;
this.noHp = noHp;
this.tglPengambilan = tglPengambilan;
this.tglPengembalian = tglPengembalian;
}
public Integer getHantaranId() {
return hantaranId;
}
public void setHantaranId(Integer hantaranId) {
Integer oldHantaranId = this.hantaranId;
this.hantaranId = hantaranId;
changeSupport.firePropertyChange("hantaranId", oldHantaranId, hantaranId);
}
public String getNamaLengkap() {
return namaLengkap;
}
public void setNamaLengkap(String namaLengkap) {
String oldNamaLengkap = this.namaLengkap;
this.namaLengkap = namaLengkap;
changeSupport.firePropertyChange("namaLengkap", oldNamaLengkap, namaLengkap);
}
public String getAlamat() {
return alamat;
}
public void setAlamat(String alamat) {
String oldAlamat = this.alamat;
this.alamat = alamat;
changeSupport.firePropertyChange("alamat", oldAlamat, alamat);
}
public String getNoHp() {
return noHp;
}
public void setNoHp(String noHp) {
String oldNoHp = this.noHp;
this.noHp = noHp;
changeSupport.firePropertyChange("noHp", oldNoHp, noHp);
}
public Date getTglPengambilan() {
return tglPengambilan;
}
public void setTglPengambilan(Date tglPengambilan) {
Date oldTglPengambilan = this.tglPengambilan;
this.tglPengambilan = tglPengambilan;
changeSupport.firePropertyChange("tglPengambilan", oldTglPengambilan, tglPengambilan);
}
public Date getTglPengembalian() {
return tglPengembalian;
}
public void setTglPengembalian(Date tglPengembalian) {
Date oldTglPengembalian = this.tglPengembalian;
this.tglPengembalian = tglPengembalian;
changeSupport.firePropertyChange("tglPengembalian", oldTglPengembalian, tglPengembalian);
}
#Override
public int hashCode() {
int hash = 0;
hash += (hantaranId != null ? hantaranId.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 Hantaran)) {
return false;
}
Hantaran other = (Hantaran) object;
if ((this.hantaranId == null && other.hantaranId != null) || (this.hantaranId != null && !this.hantaranId.equals(other.hantaranId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "aplikasi_mahar.Hantaran[ hantaranId=" + hantaranId + " ]";
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
changeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(listener);
}
}
connection class
public class MyDBConnection {
static private Connection connection;
public static Connection getConnection() throws Exception{
if(connection == null){
//JDBC
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mahardb", "root", "");
}
return connection;
}
}
Notes : i'm using persistent connection, java jdk7
You have to set new Data for your TableModel or remove deleted Data/Row from TableModel and call fireTableDataChanged method:
yourTableModel.setData(getYourData());
yourTableModel.fireTableDataChanged();

how does ".merge(entity)" work?

i'm creating a java EE (web) application using JPA and EJB for model-tier.
i think i have to use Session Beans for CRUD.
this is my BrandFacade.java (session bean)
package model.business;
import model.localinterface.BrandFacadeLocal;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import model.entities.Brand;
#Stateless
public class BrandFacade extends AbstractFacade<Brand> implements BrandFacadeLocal, BrandFacadeRemote {
#PersistenceContext(unitName = "MyWheelEE-ejbPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public BrandFacade() {
super(Brand.class);
}
#Override
public boolean CreateBrand(String name) {
Brand brand=new Brand(0, name);
boolean result=true;
try {
em.persist(brand);
} catch (Exception e) {
result=false;
}
em.close();
return result;
}
#Override
public void deleteBrand(int brandOid) {
em.remove(getBrandByOid(brandOid));
em.flush();
}
#Override
public Brand getBrandByOid(int brandOid) {
em.flush();
return em.find(Brand.class, brandOid);
}
#Override
public void editBrand(Brand brand) {
em.merge(brand);
em.flush();
}
}
and this is my Brand.java class (entity)
package model.entities;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
#Entity
#Table(name = "brand")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Brand.findAll", query = "SELECT b FROM Brand b"),
#NamedQuery(name = "Brand.findByOid", query = "SELECT b FROM Brand b WHERE b.oid = :oid"),
#NamedQuery(name = "Brand.findByName", query = "SELECT b FROM Brand b WHERE b.name = :name")})
public class Brand implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "oid")
private Integer oid;
#Basic(optional = false)
#Column(name = "name")
private String name;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "brandOid")
private List<Wheelchair> wheelchairList;
public Brand() {
}
public Brand(Integer oid) {
this.oid = oid;
}
public Brand(Integer oid, String name) {
this.oid = oid;
this.name = name;
}
public Integer getOid() {
return oid;
}
public void setOid(Integer oid) {
this.oid = oid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlTransient
public List<Wheelchair> getWheelchairList() {
return wheelchairList;
}
public void setWheelchairList(List<Wheelchair> wheelchairList) {
this.wheelchairList = wheelchairList;
}
#Override
public int hashCode() {
int hash = 0;
hash += (oid != null ? oid.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 Brand)) {
return false;
}
Brand other = (Brand) object;
if ((this.oid == null && other.oid != null) || (this.oid != null && !this.oid.equals(other.oid))) {
return false;
}
return true;
}
#Override
public String toString() {
return "model.entities.Brand[ oid=" + oid + " ]";
}
}
i wish to know how does .merge method work... i think it search in the DB the entity which has the primary key of the entity passed and then it works on edited fields right?
but how i can edit a brand knowing only the name?
It's quite simple really, here your answers:
I wish to know how does .merge method work...
When you call merge method, JPA will verify if the field marked as primary key (#Id) is not null:
- IF YES: JPA will create a new record in your database
- IT NOT: JPA will update your record using the id field value, something like (UPDATE table_name ..... WHERE id=?)
So, you are right :)
but how i can edit a brand knowing only the name?
If you wanna edit a record knowing another field rather than Id field, you will have 2 options:
1. Write JPQL, something like:
UPDATE Person p SET p.lastName = 'New Last Name' WHERE p.name = 'his name'
Write a Native Query, in this case, you will write PLAIN SQL and the run it
In both cases, you will need to do something like:
Query query = em.createQuery or em.createNativeQuery
and then just execute it

Join table with column. How is possible?

Anybody to know something about this kind of queries:
#Entity
#Table(name="ACCOUNT")
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#NamedQueries({
#NamedQuery(name = Account.GET_EXPIRATION_DATE, query="SELECT account.expirationDate FROM " +
"Domain domain JOIN domain.account WHERE domain.id = :domainId"),
#NamedQuery(name = Account.GET_BALANCE, query="SELECT account.balance FROM " +
"Domain domain JOIN domain.account WHERE domain.id = :domainId")
})
I dont understand what is this "Domain domain JOIN domain.account" we can join one table with another but it seams we join table with column .. ?
these are the related classes:
package com.smsoffice.admin;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import static javax.persistence.CascadeType.*;
import com.smsoffice.billing.Account;
import com.smsoffice.billing.PrepaidAccount;
#Entity
#Table(name="DOMAIN")
#NamedQueries({
#NamedQuery(name=Domain.GET_ALL_DOMAINS, query="SELECT d FROM Domain d ORDER BY d.name"),
#NamedQuery(name=Domain.GET_ACCOUNT, query="SELECT d.account FROM Domain d WHERE d.id = :id"),
#NamedQuery(name=Domain.GET_DOMAIN_BY_STATUS, query="SELECT d FROM Domain d WHERE d.enabled = :enabled ORDER BY d.name"),
#NamedQuery(name=Domain.GET_DOMAIN_BY_NAME, query="SELECT d FROM Domain d WHERE d.name = :name")
})
public class Domain implements Serializable {
private static final long serialVersionUID = 1L;
public final static String GET_ALL_DOMAINS = "Domain.getAllDomains";
public final static String GET_ACCOUNT = "Domain.getAccount";
public final static String GET_DOMAIN_BY_STATUS = "Domain.getAllDomainsByStatus";
public final static String GET_DOMAIN_BY_NAME = "Domain.getDomainByName";
public final static transient Domain ROOT = new Domain("ROOT");
public static Domain SYSTEM_DOMAIN = new Domain("SYSTEM");
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(unique = true, length = 96)
private String name;
//unique id of the service - one per domain
#GeneratedValue(strategy = GenerationType.AUTO)
private int serviceId;
//indicates whether the domain is enabled
private Boolean enabled = true;
//short code for the domain sms events
private int shortCode;
//prefix for parsing
private String prefix;
private String clientPrefix = "";
//bank account
#OneToOne(cascade = {PERSIST, REFRESH, REMOVE})
private Account account = new PrepaidAccount();
#OneToMany
private Set<User> users = new HashSet<User>();
public Domain() {}
public Domain(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getServiceId() {
return serviceId;
}
public void setServiceId(int serviceId) {
this.serviceId = serviceId;
}
public int getShortCode() {
return shortCode;
}
public void setShortCode(int shortCode) {
this.shortCode = shortCode;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public Set<User> getUsers() {
return users;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Domain)) {
return false;
}
Domain domain = (Domain) obj;
return getName().toUpperCase().equals(domain.getName().toUpperCase());
}
#Override
public int hashCode() {
return getName().toUpperCase().hashCode();
}
#Override
public String toString() {
return "[" + name + "("+ account + ")]";
}
public int getId() {
return id;
}
public void setClientPrefix(String clientPrefix) {
this.clientPrefix = clientPrefix != null ? clientPrefix : "";
}
public String getClientPrefix() {
return clientPrefix;
}
}
and this one:
package com.smsoffice.billing;
import static javax.persistence.CascadeType.ALL;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name="ACCOUNT")
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#NamedQueries({
#NamedQuery(name = Account.GET_EXPIRATION_DATE, query="SELECT account.expirationDate FROM " +
"Domain domain JOIN domain.account account WHERE domain.id = :domainId"),
#NamedQuery(name = Account.GET_BALANCE, query="SELECT account.balance FROM " +
"Domain domain JOIN domain.account account WHERE domain.id = :domainId")
})
public abstract class Account {
public static final MathContext MATH_CONTEXT = new MathContext(9, RoundingMode.HALF_UP);
public static final int SCALE = 3;
public static final int PRECISION = 9;
public static final String GET_BALANCE = "Account.getBalance";
public static final String GET_EXPIRATION_DATE = "Account.getExpirationDate";
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#Column(precision = PRECISION, scale = SCALE)
protected BigDecimal balance = BigDecimal.ZERO;
#OneToOne(cascade = ALL)
protected Tariff tariff;
private Date activationDate = new Date();
private Date expirationDate;
public Account() {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, 1);
setExpirationDate(calendar.getTime());
}
public BigDecimal getBalance() {
return balance;
}
public Tariff getTariff() {
return tariff;
}
public void setTariff(Tariff tariff) {
this.tariff = tariff;
}
void deposit(BigDecimal amount) {
balance = balance.add(amount).setScale(SCALE, MATH_CONTEXT.getRoundingMode());
}
abstract boolean hasCredit(int eventCount);
abstract void makePayment(int eventCount) throws PaymentException;
public int getId() {
return id;
}
public Date getActivationDate() {
return activationDate;
}
public void setActivationDate(Date activationDate) {
this.activationDate = normalizeActivationDate(activationDate);
}
void setExpirationDate(Date expirationDate) {
this.expirationDate = normalizeExpirationDate(expirationDate);
}
public Date getExpirationDate() {
return expirationDate;
}
public boolean isExpired() {
Date now = new Date();
return now.after(expirationDate);
}
#Override
public String toString() {
return "[balance: " + balance + "; tariff: " + (tariff != null ? tariff.getPrice() : "no tariff") + "; expiration date: " + expirationDate.toString() + "]";
}
public void setBalance(BigDecimal newBalance) {
this.balance = newBalance;
}
private static final Date normalizeActivationDate(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
private static final Date normalizeExpirationDate(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
}
Well, these are not really SQL queries, but rather JPQL queries - there is a very good tutorial describing this, along with very nice examples. Note that in JPQL you do not work directly with the tables, bur rather with entities of your domain model.
But to your question, let's take this query as an example:
SELECT account.balance FROM Domain domain JOIN domain.account WHERE domain.id = :domainId
SELECT account.balance will return the value of balance attribute of the account that was JOINed to the given domain record
FROM Domain domain says that Domain entity will be used to query the data from related table, defined on the Domain entity using #Table(name="DOMAIN"); the lowercase domain is just an alias to be used within this query (see e.g. the WHERE portion of the query)
JOIN domain.account will be used, together with annotation #OneToOne(cascade = {PERSIST, REFRESH, REMOVE}) defined on the account field of Domain entity, to get the relevant record from the table represented by Account entity
WHERE domain.id = :domainId will limit the results to return only the Domain with the given id, together with its account; the part :domainId is a "query parameter" and is most likely replaced somewhere in the code with an actual value, using code like query.setParameter("domainId", someValue);
So the whole query should return value of BigDecimal type (see field balance defined in Account entity).

Java persistence: named queries. Multiple parameters changes boolean values to int?

I'm an amateur programmer and I'm having trouble with the java eclipse persistence named queries. I have an entity class. In this class I have created named queries. With the ClientInformation.getList I have two parameters. One on active (Boolean) and one on type (int). When I remove either one it works like a charm, but when I try them both it transforms the boolean value to an integer.
Entity class
package datamodel;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#Table(name = "CLIENT_INFORMATION")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "ClientInformation.getList", query =
"SELECT c.ciName FROM ClientInformation c WHERE "
+ "(c.ciActive = true or c.ciActive = :ciActive) AND "
+ "(:ciType = 0 OR c.ciType = :ciType)"),
#NamedQuery(name = "ClientInformation.getID", query = "SELECT c.ciId FROM ClientInformation c WHERE c.ciName like :ciName"),
#NamedQuery(name = "ClientInformation.findAll", query = "SELECT c FROM ClientInformation c"),
#NamedQuery(name = "ClientInformation.findByCiId", query = "SELECT c FROM ClientInformation c WHERE c.ciId = :ciId"),
#NamedQuery(name = "ClientInformation.findByCiType", query = "SELECT c FROM ClientInformation c WHERE c.ciType = :ciType")})
public class ClientInformation implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "CI_ID")
private Integer ciId;
#Lob
#Column(name = "CI_NAME", unique=true)
private String ciName;
#Lob
#Column(name = "CI_ADDRESS")
private String ciAddress;
#Lob
#Column(name = "CI_AREACODE")
private String ciAreacode;
#Lob
#Column(name = "CI_CITY")
private String ciCity;
#Lob
#Column(name = "CI_PHONE")
private String ciPhone;
#Lob
#Column(name = "CI_PHONE2")
private String ciPhone2;
#Lob
#Column(name = "CI_EMAIL")
private String ciEmail;
#Column(name = "CI_ACTIVE")
private Boolean ciActive;
#Lob
#Column(name = "CI_NOTE")
private String ciNote;
#Column(name = "CI_TYPE")
private Integer ciType;
public ClientInformation() {
}
public ClientInformation(Integer ciId) {
this.ciId = ciId;
}
public Integer getCiId() {
return ciId;
}
public void setCiId(Integer ciId) {
this.ciId = ciId;
}
public String getCiName() {
return ciName;
}
public void setCiName(String ciName) {
this.ciName = ciName;
}
public String getCiAddress() {
return ciAddress;
}
public void setCiAddress(String ciAddress) {
this.ciAddress = ciAddress;
}
public String getCiAreacode() {
return ciAreacode;
}
public void setCiAreacode(String ciAreacode) {
this.ciAreacode = ciAreacode;
}
public String getCiCity() {
return ciCity;
}
public void setCiCity(String ciCity) {
this.ciCity = ciCity;
}
public String getCiPhone() {
return ciPhone;
}
public void setCiPhone(String ciPhone) {
this.ciPhone = ciPhone;
}
public String getCiPhone2() {
return ciPhone2;
}
public void setCiPhone2(String ciPhone2) {
this.ciPhone2 = ciPhone2;
}
public String getCiEmail() {
return ciEmail;
}
public void setCiEmail(String ciEmail) {
this.ciEmail = ciEmail;
}
public Boolean getCiActive() {
return ciActive;
}
public void setCiActive(Boolean ciActive) {
this.ciActive = ciActive;
}
public String getCiNote() {
return ciNote;
}
public void setCiNote(String ciNote) {
this.ciNote = ciNote;
}
public Integer getCiType() {
return ciType;
}
public void setCiType(Integer ciType) {
this.ciType = ciType;
}
#Override
public int hashCode() {
int hash = 0;
hash += (ciId != null ? ciId.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 ClientInformation)) {
return false;
}
ClientInformation other = (ClientInformation) object;
if ((this.ciId == null && other.ciId != null) || (this.ciId != null && !this.ciId.equals(other.ciId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "manager.ClientInformation[ ciId=" + ciId + " ]";
}
}
Code snip where I call the named query.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("ManagerPU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
List clientList = em.createNamedQuery("ClientInformation.getList")
.setParameter("ciActive", this.inactiveClientSelected)
.setParameter("ciType", this.typeClientSelected)
.getResultList();
clientList_ComboBox.addItem("Kies klant...");
if (clientList.isEmpty() == false) {
for (Object clientList1 : clientList) {
clientList_ComboBox.addItem(clientList1);
}
}
em.close();
emf.close();
This is the message I'm getting.
Call: SELECT CI_NAME FROM CLIENT_INFORMATION WHERE (((CI_ACTIVE = 1)
OR (CI_ACTIVE = 1)) AND ((0 = 0) OR (CI_TYPE = 0))) Internal
Exception: java.sql.SQLSyntaxErrorException: Comparisons between
'BOOLEAN' and 'INTEGER' are not supported. Types must be comparable.
String types must also have matching collation. If collation does not
match, a possible solution is to cast operands to force them to the
default collation (e.g. SELECT tablename FROM sys.systables WHERE
CAST(tablename AS VARCHAR(128)) = 'T1') Query:
ReportQuery(name="ClientInformation.getList"
referenceClass=ClientInformation sql="SELECT CI_NAME FROM
CLIENT_INFORMATION WHERE (((CI_ACTIVE = ?) OR (CI_ACTIVE = ?)) AND ((?
= ?) OR (CI_TYPE = ?)))") Error Code: 30000 Call: SELECT CI_NAME FROM CLIENT_INFORMATION WHERE (((CI_ACTIVE = 1) OR (CI_ACTIVE = 1)) AND ((0
= 0) OR (CI_TYPE = 0))) Query: ReportQuery(name="ClientInformation.getList"
referenceClass=ClientInformation sql="SELECT CI_NAME FROM
CLIENT_INFORMATION WHERE (((CI_ACTIVE = ?) OR (CI_ACTIVE = ?)) AND ((?
= ?) OR (CI_TYPE = ?)))")
Any suggestions or do I need to give more information?
Edit: When I remove the last part from the query ("... AND (:ciType = ...etc) the query works fine, so I think I ruled out the actual parameter passing/ the code passes a boolean. Also, when I remove the first parameter (the Boolean) it works as well. So It's (the combination of) the two parameters.

How to join non primary key in google app engine

How to get data of non primary key column userId using java in google app engine
List<UserAddress> list = (List<UserAddress>) pmf.getObjectById(UserAddress.class, Long.valueOf(userId));
System.out.println(list.size());
When I fetch the data the following error occur in console
NestedThrowablesStackTrace:
Could not retrieve entity of kind UserAddress with key UserAddress(4)
org.datanucleus.exceptions.NucleusObjectNotFoundException: Could not retrieve entity of kind UserAddress with key UserAddress(4)
Tried below code also, to fetch the data of non primary key column userId but it shows empty list.
#SuppressWarnings("unchecked")
public List<UserAddress> getUserAddressFind(String userId) {
List<UserAddress> returnList = new ArrayList<UserAddress>();
PersistenceManager pmf = PMF.get().getPersistenceManager();
try {
Query query = pmf.newQuery(UserAddress.class);
query.setFilter("userId == userIdParam");
query.declareParameters("Long userIdParam");
returnList = (List<UserAddress>) query.execute(userId);
System.out.println(returnList.size());
if (returnList != null && returnList.isEmpty()) {
System.out.println("No results for userAddresses");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
pmf.close();
}
return returnList;
}
UserAddress.java
package com.rrd.up2me.datastore;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
#PersistenceCapable(identityType = IdentityType.APPLICATION)
public class UserAddress {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.SEQUENCE)
private Long userAddressId;
#Persistent
private Long userId;
#Persistent
private Long addressId;
#Persistent
private Boolean isPrimary;
public Long getUserAddressId() {
return userAddressId;
}
public void setUserAddressId(Long userAddressId) {
this.userAddressId = userAddressId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getAddressId() {
return addressId;
}
public void setAddressId(Long addressId) {
this.addressId = addressId;
}
public Boolean getIsPrimary() {
return isPrimary;
}
public void setIsPrimary(Boolean isPrimary) {
this.isPrimary = isPrimary;
}
}
In UserAddress.java class userId is long when execute the query passed variable type is Stringso data is not fetching. AfterType cast the userId String to Long problem solved.
Ex: Long.valueOf(userId).
Query query = pmf.newQuery(UserAddress.class);
query.setFilter("userId == userIdParam");
query.declareParameters("Long userIdParam");
returnList = (List<UserAddress>) query.execute(Long.valueOf(userId));
System.out.println(returnList.size());

Categories