ormlite update not null field - java

I want update only not null field. I have some class like below
#DatabaseTable
public class ClickCount implements Serializable {
private static final long serialVersionUID = -6582623980712135028L;
public static final String DATE_FIELD_NAME = "lastClickDate";
#DatabaseField(generatedId = true)
private Integer id;
#DatabaseField(columnName = DATE_FIELD_NAME)
private Date lastClickDate;
#DatabaseField(index = true)
private String name;
#DatabaseField
private String description;
#DatabaseField
private int value;
#DatabaseField(canBeNull = true, foreign = true)
private ClickGroup group;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public ClickGroup getGroup() {
return group;
}
public void setGroup(ClickGroup group) {
this.group = group;
}
public Date getLastClickDate() {
return lastClickDate;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
/**
* This updates the value and adjusts the date.
*/
public void changeValue(int value) {
this.value = value;
this.lastClickDate = new Date();
}
#Override
public String toString() {
return name + " " + value;
}
}
I get some json and parse with ClickCount class, but some field may be null. When I update data in DB null field writing into DB. How write only not null field?
Updating data below
Dao<ClickCount, Integer> dao = getHelper().getClickDao();
ClickCount clickCountInDb = dao.queryForAll().get(0);
ClickCount clickCountFromServer = getFromServer();
clickCountFromServer.setId(clickCountInDb.getId());
dao.update(clickCountFromServer);

You have update each field manually after checking if its null or not. After that just update your fetched entity like this:
Dao<ClickCount, Integer> dao = getHelper().getClickDao();
ClickCount clickCountFromServer = getFromServer();
ClickCount clickCountInDb = dao.queryForId(clickCountInDb.getId()); // query for specific item. After this you should check if the query was succesful.
if (clickCountFromServer.getLastClickDate() != null)
{
clickCountInDb.setLastClickDate(clickCountFromServer.getLastClickDate());
}
if (clickCountFromServer.getName() != null)
{
clickCountInDb.setName(clickCountFromServer.getName());
}
// and so on for all fields
// after you set not null properties on the object clickCountInDb you have to propagate changes back to the database:
dao.update(clickCountInDb);

Related

Add record in detail in master-detail ADF in two sessions

if I have a master entity :
#Entity
public class Test implements Serializable {
#Id
#Column(name="TEST_ID" nullable = false)
private BigDecimal testId;
#Column(unique = true, length = 30)
private String code;
#Temporal(TemporalType.TIMESTAMP)
#Column(nullable = false, length = 50)
private String name;
#Column(name="SYS_VERSION_NUMBER",nullable = false, length = 50)
private Long sysVersionNumber;
#OneToMany(mappedBy = "test", orphanRemoval=true, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
private List<TestDetail> testDetailList;
public Test() {}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getTestId() {
return testId;
}
public void setTestId(BigDecimal testId) {
this.testId = testId;
}
public Long getSysVersionNumber() {
return sysVersionNumber;
}
public void setSysVersionNumber(Long sysVersionNumber) {
this.sysVersionNumber = sysVersionNumber;
}
public List<TestDetail> getTestDetailList() {
return testDetailList;
}
public void setTestDetailList(List<TestDetail> testDetailList) {
this.testDetailList = testDetailList;
}
public TestDetail addTestDetailList(TestDetail testDetail) {
getTestDetailList().add(testDetail testDetail);
testDetail.setTest(this);
testDetail.setTestId(this.getTestId());
return testDetail;
}
public TestDetail removeProvbilling(TestDetail testDetail) {
getTestDetailList().remove(testDetail testDetail);
testDetail.setTest(null);
testDetail.setTestId(null);
return testDetail;
}
#Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof Test)) {
return false;
}
final Test other = (Test) object;
if (!(id == null ? other.testId == null : testId.equals(other.testId))) {
return false;
}
return true;
}
#Override
public int hashCode() {
final int PRIME = 37;
int result = 1;
result = PRIME * result + ((test == null) ? 0 : test.hashCode());
return result;
}
}
and I have a detail entity
#Entity
public class Testdetail implements Serializable {
#Id
#Column(name = "TESTDETAIL_ID", nullable = false)
private BigDecimal testdetailId;
#Version
#Column(name = "SYS_VERSION_NUMBER")
private Long sysVersionNumber;
#ManyToOne
#JoinColumn(name = "TEST_ID", insertable=false, updatable=false)
private TEST test;
#Column(name = "TEST_ID",)
private BigDecimal testId;
#Column
private String name;
public Testdetail() {
}
public Test getTest() {
return test;
}
public void setTest(Test test) {
this.test = test;
}
public void setTestId(BigDecimal testId) {
this.testId = testId;
}
public BigDecimal getTestId() {
return testId;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public Long getSysVersionNumber() {
return sysVersionNumber;
}
public void setSysVersionNumber(Long sysVersionNumber) {
this.sysVersionNumber = sysVersionNumber;
}
}
if I run the page in twice two tabs with the same Test record and add new record for 'testDetail' in the first tab then add record for 'testDetail' in second tab (I am calling method mergeTest() in sessionbean which invoke em.merge(test) on saving), the added record in fist tab is gone even though sysversionnumber is working properly to prevent user from editing existing records if they were edited in the second tab.
is there a way to prevent user from adding record in second tab or to lock master record if it is used through EntityManager in sessionBean?
I found a solution after calling em.merge(test); I have to lock it using
em.lock(test, LockModeType.OPTIMISTIC_FORCE_INCREMENT);

Generic AttributeConverter for Enums in Spring Boot

I want to create a Generic class which implements AttributeConverter and can be used in #Converter annotation for all enums.
I have two different enums each one has a converter class but both converter classes are doing same thing.
The following are the code Snippet.
public enum Type {
BASIC(1, "Basic"),
ADVANCE(2, "Advance");
private final Integer id;
private final String name;
private Type(Integer id, String name) {
this.id = id;
this.name = name;
}
public static Type getType(Integer id) {
if (id == null) { return null; }
for (Type type: Type.values()) {
if (id == type.getId()) {
return type;
}
}
return null;
}
public Integer getId() { return id; }
public String getName() { return name; }
}
#Converter(autoApply = true)
public class TypeConverter implements AttributeConverter<Type, Integer> {
#Override
public Integer convertToDatabaseColumn(Type type) {
return type.getId();
}
#Override
public Type convertToEntityAttribute(Integer databaseValue) {
return Type.getType(databaseValue);
}
}
public enum State {
FIRST(1, "First"),
SECOND(2, "Second");
private final Integer id;
private final String name;
private State(Integer id, String name) {
this.id = id;
this.name = name;
}
public static State getState(Integer id) {
if (id == null) { return null; }
for (State state: State.values()) {
if (id == state.getId()) {
return state;
}
}
return null;
}
public Integer getId() { return id; }
public String getName() { return name; }
}
#Converter(autoApply = true)
public class StateConverter implements AttributeConverter<State, Integer> {
#Override
public Integer convertToDatabaseColumn(State state) {
return state.getId();
}
#Override
public State convertToEntityAttribute(Integer databaseValue) {
return State.getState(databaseValue);
}
}
#Table(name = "um_user")
public class User
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String username;
private String password
#Convert(converter = TypeConverter.class)
private Type type;
#Convert(converter = StateConverter.class)
private State state;
}
Now I want to create a generic converter that can be used instead of both TypeConverter & StateConverter.

show all list query java hibernate

i have this function to query in hibernate:
public List<TransactionQR> getAllTransaction() throws HibernateException {
return this.session.createQuery("SELECT id FROM TransactionQR").list();
}
then is success to show the data like this in html:
[2, 3]
but when i add more column in SELECT like this:
public List<TransactionQR> getAllTransaction() throws HibernateException {
return this.session.createQuery("SELECT id, codeqr FROM TransactionQR").list();
}
the result show like this:
[Ljava.lang.Object;#25026824, [Ljava.lang.Object;#170b75f9]
what is Ljava.lang.Object;#25026824 ? is return object, can i handle it to convert from list to json ?
i have model TransactionQR.java :
public class TransactionQR implements Serializable {
private Long id;
private String codeqr;
private Date approvaltime;
private String merchant;
private String code_merchant;
private Long amount;
private Long saldoawal;
private Integer tracenumber;
private String state;
private Date createdate;
private Batch batch;
public TransactionQR() {
}
public TransactionQR(Long id, String codeqr, Date approvaltime, String merchant, String code_merchant, Long amount,
Long saldoawal, Integer tracenumber, String state, Date createdate, Batch batch) {
super();
this.id = id;
this.codeqr = codeqr;
this.approvaltime = approvaltime;
this.merchant = merchant;
this.code_merchant = code_merchant;
this.amount = amount;
this.saldoawal = saldoawal;
this.tracenumber = tracenumber;
this.state = state;
this.createdate = createdate;
this.batch = batch;
}
public Long getId() {
return id;
}
public Date getApprovalTime() {
return approvaltime;
}
public Batch getBatch() {
return batch;
}
public void setBatch(Batch batch) {
this.batch = batch;
}
public void setApprovalTime(Date approvalTime) {
this.approvaltime = approvalTime;
}
public void setId(Long id) {
this.id = id;
}
public Date getApprovaltime() {
return approvaltime;
}
public void setApprovaltime(Date approvaltime) {
this.approvaltime = approvaltime;
}
public String getCodeqr() {
return codeqr;
}
public void setCodeqr(String codeqr) {
this.codeqr = codeqr;
}
public String getMerchant() {
return merchant;
}
public void setMerchant(String merchant) {
this.merchant = merchant;
}
public String getCode_merchant() {
return code_merchant;
}
public void setCode_merchant(String code_merchant) {
this.code_merchant = code_merchant;
}
public Long getAmount() {
return amount;
}
public void setAmount(Long amount) {
this.amount = amount;
}
public Long getSaldoawal() {
return saldoawal;
}
public void setSaldoawal(Long saldoawal) {
this.saldoawal = saldoawal;
}
public Integer getTracenumber() {
return tracenumber;
}
public void setTracenumber(Integer tracenumber) {
this.tracenumber = tracenumber;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Date getCreatedate() {
return createdate;
}
public void setCreatedate(Date createdate) {
this.createdate = createdate;
}
}
the result is i want to show all data from database in list
In second case, since you are selecting two attributes, that is why session.createQuery("").list returns a list of object array(List<Object[]>) . At each index of list you will find an object array. Each array will have two indexes. First index will provide id while the second one would provide codeqr. So, basically you need to iterate over the list. Then fetch each value individually like arr[0], arr[1]..

Hibernate #ManyToOne #JoinColumn is always null

I'm trying to implement One-to-Many relation between two tables using hibernate. Here is my code:
#Entity
public class Board
{
#Id
#Column(name = "board_id")
#GeneratedValue
private long id;
#Column
private String owner;
#Column
private String title;
#Column
private String refresh;
#Column
private Timestamp createDate;
#Column
private Timestamp modifyDate;
#OneToMany(mappedBy="board", cascade=CascadeType.ALL)
private List<Item> items;
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getOwner()
{
return owner;
}
public void setOwner(String owner)
{
this.owner = owner;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getRefresh()
{
return refresh;
}
public void setRefresh(String refresh)
{
this.refresh = refresh;
}
public Timestamp getCreateDate()
{
return createDate;
}
public void setCreateDate(Timestamp createDate)
{
this.createDate = createDate;
}
public Timestamp getModifyDate()
{
return modifyDate;
}
public void setModifyDate(Timestamp modifyDate)
{
this.modifyDate = modifyDate;
}
public List<Item> getItems()
{
return items;
}
public void setItems(List<Item> items)
{
this.items = items;
}
}
and second table:
#Entity
public class Item
{
public enum Type
{
link,
image,
presentation;
}
public enum JavaScript
{
enable,
disable;
}
#Id
#Column
#GeneratedValue
private long id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "board_id")
private Board board;
#Column
private Type type;
#Column(length = 10000)
private String link;
#Column
private String image;
#Column
private String presentation;
#Column
private String time;
#Column
private JavaScript javaScript;
#Column
private String first;
#Column
private String last;
#Transient
private MultipartFile imageFile;
#Transient
private MultipartFile presentationFile;
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public Board getBoard()
{
return board;
}
public void setBoard(Board board)
{
this.board = board;
}
public Type getType()
{
return type;
}
public void setType(Type type)
{
this.type = type;
}
public String getLink()
{
return link;
}
public void setLink(String link)
{
this.link = link;
}
public String getImage()
{
return image;
}
public void setImage(String image)
{
this.image = image;
}
public String getPresentation()
{
return presentation;
}
public void setPresentation(String presentation)
{
this.presentation = presentation;
}
public String getTime()
{
return time;
}
public void setTime(String time)
{
this.time = time;
}
public JavaScript getJavaScript()
{
return javaScript;
}
public void setJavaScript(JavaScript javaScript)
{
this.javaScript = javaScript;
}
public String getFirst()
{
return first;
}
public void setFirst(String first)
{
this.first = first;
}
public String getLast()
{
return last;
}
public void setLast(String last)
{
this.last = last;
}
public MultipartFile getImageFile()
{
return imageFile;
}
public void setImageFile(MultipartFile imageFile)
{
this.imageFile = imageFile;
}
public MultipartFile getPresentationFile()
{
return presentationFile;
}
public void setPresentationFile(MultipartFile presentationFile)
{
this.presentationFile = presentationFile;
}
}
but I can't get it working. board_id is always null in item table. Hibernate output looks strange:
Hibernate: insert into Board (board_id, createDate, modifyDate, owner, refresh, title) values (null, ?, ?, ?, ?, ?)
Hibernate: insert into Item (id, board_id, first, image, javaScript, last, link, presentation, time, type) values (null, ?, ?, ?, ?, ?, ?, ?, ?, ?)
any ideas?
To expand on the comment by #Antoniossss, you need to set the relation on both sides before persisting.
// Create owning entity first
Board board = new Board();
// Create child entities
Item item1 = new Item();
item1.setBoard(board); // set relation on Item side
board.getItems().add(item1); // set relation on Board side
Also note that it is considered good practice to initialize collection fields immediately, so that Board#getItems() never returns null.
Quick tip:
When using #GeneratedValue for an #Id field, it's best to avoid explicitly setting a value on that field.
#GeneratedValue means that either Hibernate or your database of choice will set the entity's id(either of which depends on your GenerationType), so setting an explicit value or allowing it to be publicly set possibly will result in throwing a Hibernate-specific StaleStateException.
So you should not include id in your constructor and also remove:
public void setId(long id)
{
this.id = id;
}

I Can't Update table with ormlite android

The problem is that I have a table product and my update script doesn't work aparently. It allwas return false.
Product.class
#DatabaseTable(tableName = "Product")
public class Product {
#DatabaseField(index = true, generatedId = true)
private int productId;
#DatabaseField
private String name;
#DatabaseField
private int quantity;
//#DatabaseField(canBeNull = true)
//private Integer categorie;
//http://logic-explained.blogspot.com.ar/2011/12/using-ormlite-in-android-projects.html
#DatabaseField
private int categorie;
//#ForeignCollectionField
//private ForeignCollection<Categorie> itemsCategorie;
#DatabaseField
private String description;
#DatabaseField
private String photo;
Product() {
}
public Product(int productId, String name, int quantity, int categorie, String description, String photo) {
super();
this.productId = productId;
this.name = name;
this.quantity = quantity;
this.categorie = categorie;
this.description = description;
this.photo = photo;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return description;
}
public void setAddress(String address) {
this.description = address;
}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getCategorie() {
return categorie;
}
public void setCategorie(int categorie) {
this.categorie = categorie;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public CharSequence getDesc() {
return null;
}
}
my script updateProduct
public boolean updateProduct(Product p) {
boolean ret = false;
if (productDao != null) {
try {
productDao = getDao(Product.class);
UpdateBuilder<Product, Integer> updateBuilder = productDao
.updateBuilder();
updateBuilder.updateColumnValue("name", p.getName());
updateBuilder.updateColumnValue("quantity", p.getQuantity());
updateBuilder.updateColumnValue("categorie", p.getCategorie());
updateBuilder.updateColumnValue("description", p.getDesc());
updateBuilder.updateColumnValue("photo", p.getPhoto());
// but only update the rows where the description is some value
updateBuilder.where().eq("productId", p.getProductId());
// actually perform the update
String str = updateBuilder.prepareStatementString();
// UPDATE `Product` SET `name` = 'gcd' ,`quantity` = 1
// ,`categorie` = 1 ,`description` = ? ,`photo` = '' WHERE
// `productId` = 0
if (productDao.update(updateBuilder.prepare()) != 1) {
ret = false;
} else {
productDao.refresh(p);
ret = true;
}
} catch (Exception e) {
ret = false;
e.printStackTrace();
}
}
return ret;
}
then I call it with a function like this, but allways return false :(
public boolean updateProduct(Product p) {
boolean ret = false;
try {
ret = getHelper().updateProduct(p);
} catch (Exception e) {
e.printStackTrace();
ret =false;
}
return ret;
}
I can create and delete but I can not update . I tried everything.
If you please take a moment to answer my question I will appreciate.
for other developers, if you come face to face with a problem like this you should ensure the table must have an identity key.
#DatabaseTable(tableName = "User")
public class User {
#DatabaseField(generatedId = true)
public int id;
#DatabaseField
public String ServiceUserId;
#DatabaseField
public boolean IsActive;
#DatabaseField
public String FirstName;
#DatabaseField
public String LastName;
#DatabaseField
public String Key;
#DatabaseField
public String Email;
}
The solution was
Simply get the Instance of the object Product from the DB then modify to finaly send to the updateProduct method.
for example first I need to create any method first to get an objet by ID
// get the Instance calling to the getProductByID
Product p = getHelper().getProductByID(p.getId())
//modify any value of the product
p.setFirstName("asd");
//call the update
ret = getHelper().updateProduct(p);
then my objects is Updated.
Put attention for the object Id(should be the same) and use the natif function update(Product);
In your case, you must override equals and hashCode.

Categories

Resources