Why Select query incrementing #Version - java

The version for the class Application is getting incremented after the execution of the following statement
Queue queue = queueDao.fetchQueueByApplicationId(application.getApplicationId());
It is a simple fetch query only and it should not increment the version of the call any how. But after above line execution the version is getting incremented unexpectedly for Application class
Could someone please help
Thanks.
Queue.java
#Entity
#Table(name = "queue")
#NamedQuery(name = "queueByApplicationId", query = "SELECT q from Queue q WHERE q.application.applicationId = ?")
public class Queue implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "queue_id", unique = true, nullable = false)
private Long queueId;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "created", nullable = false, length = 19)
private Date created;
#Column(name = "created_by")
private Long createdBy;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updated", length = 19)
private Date updated;
#Column(name = "updated_by")
private Long updatedBy;
#Version
#Column(name = "version", nullable = false)
private Integer version;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "application_id")
private Application application;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "queue", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
private List<QueueAssignedToRole> queueAssignedToRoles;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "queue", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
private List<QueueAssignedUser> queueAssignedUsers;
getter setter ....
}
Application.java
#Entity
#Table(name = "application")
public class Application implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Long applicationId;
private Integer version;
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "application_id", unique = true, nullable = false)
public Long getApplicationId() {
return this.applicationId;
}
public void setApplicationId(Long applicationId) {
this.applicationId = applicationId;
}
#Version
#Column(name = "version", nullable = false)
public Integer getVersion() {
return this.version;
}
public void setVersion(Integer version) {
this.version = version;
}
}
ApplicationQueueDaoImpl.java
#Repository
public class ApplicationQueueDaoImpl extends AbstractDao<Queue> {
private static final Logger LOGGER = LogManager.getLogger(ApplicationQueueDaoImpl.class);
#Override
public Queue fetchQueueByApplicationId(Long applicationId) {
LOGGER.debug("Fetching Queue information for applicationId {}", applicationId);
List<Queue> queues = executeNamedQuery("queueByApplicationId", Queue.class, applicationId);
return CollectionUtils.isEmpty(queues) ? null : queues.get(0);
}
}
AbstractDao.java
protected <T> List<T> executeNamedQuery(String queryName, Class<T> resultType, Object... positionalParams) {
TypedQuery<T> query = entityManager.createNamedQuery(queryName, resultType);
DAOUtils.setPositionalParams(query, positionalParams);
return query.getResultList();
}

Related

hibernate session save method not working?

I 'm new in spring and hibernate. i have a sample project that not work properly. when i try to save new order from user, i get no error or exceprion, but record not inserted into database.
here my code
strong textStoreController.java
#Autowired
OrderService orderService;
#SuppressWarnings("unchecked")
#RequestMapping(value = "/store/addorder", method = RequestMethod.GET)
public ModelAndView addOrder(HttpSession session) {
ModelAndView model = new ModelAndView();
// create list of products that we have to add in orders
List<CartItem> items = (List<CartItem>) session.getAttribute("cart");
Set<CartItem> itemsSet = new HashSet<CartItem>();
// new order generated and setter methods invoke
Orders order = new Orders(itemsSet);
Date d = new Date();
Date delivery = StoreUtils.deliveryDate(d, 3);
order.setOrderDate(d);
order.setDeliveryDate(delivery);
order.setItems(itemsSet);
for (CartItem cartItem : items) {
itemsSet.add(cartItem);
}
String addOrders = orderService.addOrders(order);
System.err.println("new order add status " + addOrders + "-------------");
// change product quantity after adding new order
if (!addOrders.toLowerCase().contains("error")) {
for (int i = 0; i < items.size(); i++) {
Integer qSale = items.get(i).getQuantity() * (-1);
productService.rechargeProduct(items.get(i).getProduct(), qSale);
}
model.setViewName("successorder");
model.addObject("order", order);
model.addObject("message", addOrders);
session.setAttribute("cart", null);
} else {
session.setAttribute("error", addOrders);
model.setViewName("redirect:/addtocartlist");
}
return model;
}
Orders.java
#Entity
#Table(name = "orders")
public class Orders implements Serializable {
private static final long serialVersionUID = -3672662224925418969L;
#Id
#Column(name = "orderid", nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#DateTimeFormat(pattern = "yyyy-mm-dd")
#Column(name = "orderDate", nullable = false)
private Date orderDate;
#DateTimeFormat(pattern = "yyyy-mm-dd")
#Column(name = "delivery", nullable = false)
private Date deliveryDate;
#Column(name = "success", nullable = true, columnDefinition = "tinyint(1) default 0")
private boolean success;
#Column(name = "cancel", nullable = true, columnDefinition = "tinyint(1) default 0")
private boolean canceled;
#Column(name = "cause", nullable = true)
private String cancelCause;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinTable(name = "ORDERS_ITEMS", joinColumns = { #JoinColumn(name = "orderid") }, inverseJoinColumns = {
#JoinColumn(name = "item_id") })
private Set<CartItem> items = new HashSet<CartItem>(0);
//setters and getters
}
CartItem.java
#Entity
#Table(name = "items")
public class CartItem implements Serializable {
private static final long serialVersionUID = 7968604053015663078L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "item_id", nullable = false)
private Long id;
#Column(name = "quantity", nullable = false, columnDefinition = "int(11) default 1")
private Integer quantity;
#Column(name = "totalprice", nullable = false)
private BigDecimal totalprice;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "prd_id", nullable = false)
private Product product;
//setters and getters
}
Product.java
#Entity
#Table(name = "products")
public class Product implements Serializable {
private static final long serialVersionUID = -7738539408628995177L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "prd_id")
private Long id;
#Column(name = "full_name", nullable = false)
private String fullName;
#Column(name = "seller_name")
private String seller;
#Column(name = "company_name", nullable = false)
private String companyName;
#Column(name = "created_date")
#DateTimeFormat(pattern = "yyyy-mm-dd")
private Date createdDate;
#Column(name = "expiry_date")
#DateTimeFormat(pattern = "yyyy-mm-dd")
private Date expiryDate;
#Column(name = "insert_date")
#DateTimeFormat(pattern = "yyyy-mm-dd")
private Date insertDate;
#Column(name = "likes", nullable = true)
private Integer likeCount;
#Column(name = "quantity", nullable = true)
private Integer quantity;
#Column(name = "price", nullable = false)
private BigDecimal price;
#Column(name = "category", nullable = false)
private String category;
#Column(name = "description", nullable = true)
private String description;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "product")
private Set<CartItem> items;
//setters and getters
}
and finally here is my doa implementation code
OrdersDaoImpl.java
#Repository("ordersDao")
public class OrdersDaoImpl implements OrdersDao {
#Autowired
SessionFactory sessionFactory;
protected Session session() {
try {
return sessionFactory.getCurrentSession();
} catch (HibernateException e) {
return sessionFactory.openSession();
}
}
public String addOrders(Orders orders) {
String result = "";
try {
session().save(orders);
result = "success";
} catch (Exception e) {
if (e.getMessage().toLowerCase().contains("duplicate"))
result = "error this order already was exist";
else
result = "error " + e.getMessage();
System.err.println(result);
} finally {
session().clear();
}
return result;
}
}
when i try to add new order i get no exception. why my service not work?
i have another controller in my project, that manage users. in that controller and dao implementation add and remove user working properly.
i think i have logic error in my code for one to many and many to many. please help me to overcome this fail.

How to persist entity with joining?

I am confused about how to save entry in db with column's join. I have #Entity bellow
#XmlRootElement
#XmlAccessorType(value = XmlAccessType.FIELD)
#Entity
#Table(name = "psc_users")
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 8885916014620036457L;
#Id
private static final String SEQUENCE_NAME = "psc_users_user_id_seq";
#Id
#GeneratedValue(generator = "UseExistingOrGenerateIdGenerator",
strategy = GenerationType.SEQUENCE)
#GenericGenerator(name = "UseExistingOrGenerateIdGenerator",
strategy = "com.psc.util.UseExistingOrGenerateIdGenerator",
parameters = {
#org.hibernate.annotations.Parameter(name = "sequence", value = SEQUENCE_NAME)
}
)
#Column(name = "USER_ID")
private Long userId;
#Column(name = "DEF", length = 30)
private String def;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "DEL_DATE")
private Date delDate;
#Column(name = "DISPLAY_DEF", length = 60)
private String displayDef;
#Column(name = "EMAIL", length = 60)
private String email;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "NAVI_DATE")
private Date naviDate;
#Column(name = "NAVI_USER")
private String naviUser;
#Column(name = "PHONE", length = 30)
private String phone;
#Column(name = "PWD", length = 40)
private String pwd;
//bi-directional many-to-one association to Branch
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "BRNC_BRNC_ID", nullable = false)
private Branch pscBranch;
public Long getBrncBrncId() {
return brncBrncId;
}
public void setBrncBrncId(Long brncBrncId) {
this.brncBrncId = brncBrncId;
}
#Column(name = "BRNC_BRNC_ID", insertable = false, updatable = false)
private Long brncBrncId;
//bi-directional many-to-one association to User
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "CURATOR_USER_ID")
private User pscUser;
public Long getCuratorUserId() {
return curatorUserId;
}
public void setCuratorUserId(Long curatorUserId) {
this.curatorUserId = curatorUserId;
}
#Column(name = "CURATOR_USER_ID", insertable = false, updatable = false)
private Long curatorUserId;
public User() {
}
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getDef() {
return this.def;
}
public void setDef(String def) {
this.def = def;
}
public Date getDelDate() {
return this.delDate;
}
public void setDelDate(Date delDate) {
this.delDate = delDate;
}
public String getDisplayDef() {
return this.displayDef;
}
public void setDisplayDef(String displayDef) {
this.displayDef = displayDef;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getNaviDate() {
return this.naviDate;
}
public void setNaviDate(Date naviDate) {
this.naviDate = naviDate;
}
public String getNaviUser() {
return this.naviUser;
}
public void setNaviUser(String naviUser) {
this.naviUser = naviUser;
}
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPwd() {
return this.pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public Branch getPscBranch() {
return this.pscBranch;
}
public void setPscBranch(Branch pscBranch) {
this.pscBranch = pscBranch;
}
public User getPscUser() {
return this.pscUser;
}
public void setPscUser(User pscUser) {
this.pscUser = pscUser;
}
}
if I save User instance without field pscUser (here null) but there is valid CuratorUserId with correct value I end up in a situation with empty CuratorUserId in db. If you look at code then you will see these bound fields.
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "CURATOR_USER_ID")
private User pscUser;
#Column(name = "CURATOR_USER_ID", insertable = false, updatable = false)
private Long curatorUserId;
code to save user
repositoryUser.save(user);
this i see in debugger
this i see in database after saving my user.
sorry for my stupid question but I come across on a different behavior, there is code in my project which behaves in another manner. I don't want to search actual another user(curator) for saving my user, because of overhead on query
The #Column annotation on the curetorUserId field has properties
insertable=false and updatable=false, which means that its value is ignored during inserts and updates.
You can either change these properties to true (but it can break your application in some other places) or just fill in pscUser field using EntityManager.getReference, which just creates a proxy and doesn't actualy produce a query to the database.
Your mapping should look like the below:
#XmlRootElement
#XmlAccessorType(value = XmlAccessType.FIELD)
#Entity
#Table(name = "psc_users")
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 8885916014620036457L;
#Id
private static final String SEQUENCE_NAME = "psc_users_user_id_seq";
#Id
#GeneratedValue(generator = "UseExistingOrGenerateIdGenerator",
strategy = GenerationType.SEQUENCE)
#GenericGenerator(name = "UseExistingOrGenerateIdGenerator",
strategy = "com.psc.util.UseExistingOrGenerateIdGenerator",
parameters = {
#org.hibernate.annotations.Parameter(name = "sequence", value = SEQUENCE_NAME)
}
)
#Column(name = "USER_ID")
private Long userId;
#Column(name = "DEF", length = 30)
private String def;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "DEL_DATE")
private Date delDate;
#Column(name = "DISPLAY_DEF", length = 60)
private String displayDef;
#Column(name = "EMAIL", length = 60)
private String email;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "NAVI_DATE")
private Date naviDate;
#Column(name = "NAVI_USER")
private String naviUser;
#Column(name = "PHONE", length = 30)
private String phone;
#Column(name = "PWD", length = 40)
private String pwd;
//bi-directional many-to-one association to Branch
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "BRNC_BRNC_ID", nullable = false)
private Branch pscBranch;
//bi-directional many-to-one association to User
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "CURATOR_USER_ID")
private User pscUser;
public User() {
}
}
You need to think in terms of objects. The FK will only be set in the database if you set the pscUser reference to an instance of a User. If this is an existing User then you need to set a reference to the existing persistent entity.
Real answer is that I have two points for saving and updating my entity. Please see this Hibernate: Where do insertable = false, updatable = false belong in composite primary key constellations involving foreign keys?

Embeddable/ ManyToOne/ OneToMany not working

I' m quite knew to Java and currently I am working on a ChatProgramm.
So I want to create a table Messages embedded with the ID (USERNUMBER) of my table Contacts using Injections.
Here' s the class of my Message:
#Embeddable
#Entity(name = "MESSAGE")
public class Message implements Serializable {
#ManyToOne
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "INCOME_MESSANGE", nullable = false)
private String incomingMessage;
#EmbeddedId
#JoinColumn(name = "USERNUMBER", nullable = false)
private Contact contact;
ChatApplicationRemote chatApplicationRemote;
public Message(String ip, String msg) throws IOException {
incomingMessage = msg;
contact = chatApplicationRemote.getcontactByIP(ip.toString());
}
public Message(){
}
public String getIncomingMessage() {
return incomingMessage;
}
public Contact getContact() {
return contact;
}
And here my contacts:
#Entity(name = "CONTACTS")
#Embeddable
public class Contact implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6855140755056337926L;
#Column(name = "NAME", nullable = false)
private String name;
#Column(name = "PRENAME", nullable = false)
private String vorname;
#Column(name = "IP", nullable = false)
private String ip;
#Column(name = "PORT", nullable = false)
private Integer port;
#Id
#OneToMany(mappedBy = "Message.incomingMessage")
#Column(name = "USERNUMBER", nullable = false)
private String usernumber;
public Contact(String usernumber, String name, String vorname, String ip, String port) {
super();
this.usernumber = usernumber;
this.name = name;
this.vorname = vorname;
this.ip = ip;
this.port = Integer.parseInt(port);
}
public Contact(){
}
public String getUsernumber() {
return usernumber;
}
//......
So in my Message, I get two errors:
#ManyToOne throws : Target entity "java.lang.String" is not an Entity
#EmbeddedID throws : de.nts.data.Contact is not mapped as an embeddable
So I googled for a while.. and found something abouta orm.xml which I hadn't have. And even if I create one, #EmbeddedID throws:Embedded ID class should include method definitions for equals() and hashcode() and the orm.xml Attribute "usernumber" has invalid mapping type in this context.
Can anyone please help?
Try
#Entity
public class Message implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#Column(name = "INCOME_MESSANGE", nullable = false)
private String incomingMessage;
#ManyToOne
#JoinColumn(name = "USERNUMBER", nullable = false)
private Contact contact;
#Transient
ChatApplicationRemote chatApplicationRemote;
..
}
#Entity
public class Contact implements Serializable {
private static final long serialVersionUID = -6855140755056337926L;
#Column(name = "NAME", nullable = false)
private String name;
#Column(name = "PRENAME", nullable = false)
private String vorname;
#Column(name = "IP", nullable = false)
private String ip;
#Column(name = "PORT", nullable = false)
private Integer port;
#Id
#Column(name = "USERNUMBER", nullable = false)
private String usernumber;
#OneToMany(mappedBy = "incomingMessage")
private LIst<Message> messages;
..
}
maybe as a starting point, but as JB Nizet suggested, start with some simple JPA/Java demos to get the basics first and build up. Your example has many more errors then just what the exception was showing, none of which are solved by just throwing in an ORM.xml.

Transform MySQL select to Criteria API

I have the following select statement in MySQL (sorry for the column/tables names):
SELECT a1.* FROM A a1
LEFT JOIN A a2
ON a1.DD_ID = a2.DD_ID
and a1.PRD = a2.PRD
AND a1.VN < a2.VN
LEFT JOIN B bb
ON a1.id = cc.del_id
WHERE a2.DD_ID is null
AND bb.del_id is null;
Here are the entities:
#Entity
#Table(name = "A", uniqueConstraints = {
#UniqueConstraint(columnNames = {"DD_ID", "VN", "PRD"})})
public class A
implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", unique = true, nullable = false)
private Long id;
#Column(name = "VN", nullable = false)
private Short vn;
#Column(name = "PRD", nullable = false)
#NotNull
private String prd;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "DD_ID", nullable = false)
#NotNull
private DD dd;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "A")
private Set<B> bs;
#Override
public boolean equals(final Object pOther)
{
...
}
#Override
public int hashCode()
{
...
}
// getters and setters
}
#Entity
#Table(name = "B")
public class B
implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", unique = true, nullable = false)
private Long id;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "DEL_ID", nullable = false)
#NotNull
private A a;
#Override
public boolean equals(final Object pOther)
{
...
}
// getters and setters
}
and I want to implement it using Criteria API, but I have troubles implementing the self left join from the statement.
Any suggestions?

Some parent entity value cannot be saved to child entity

When i save the job entity i was expecting that the child under job should also reflect in the db. The problem is that the ref_id and revision does not contain any value from the db.
here is the result from mysql db (removed confidential data)
This is my Job entity class
#Entity
#Table(name = "job")
public class Job implements Serializable {
private static final long serialVersionUID = -2075866246194059832L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "ref_id")
private String refId;
#Column(name = "revision")
private int revision;
#Column(name = "appname")
private String appName;
#Column(name = "vendor")
private String vendor;
#Column(name = "version")
private String version;
#Column(name = "locale")
private String locale;
#Column(name = "platform")
private String platform;
#Column(name = "tier")
private String tier;
#Column(name = "category")
private String category;
#Column(name = "functional_tag")
private String functional;
#Column(name = "job_start_date")
private Date jobStartDate;
#Column(name = "author")
private String author;
#Enumerated(EnumType.STRING)
private Status status;
#Column(name = "release_version")
private String releaseVersion;
#OneToMany(mappedBy = "job", cascade = CascadeType.PERSIST)
private List<Task> tasks;
}
And here is the child
#Entity
#Table(name = "task")
public class Task implements Serializable {
private static final long serialVersionUID = -7395753611385528546L;
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "module_name")
private String moduleName;
#Column(name = "start_time")
private Date startTime;
#Column(name = "end_time")
private Date endTime;
#Enumerated(EnumType.STRING)
private Status status;
#Column(name = "machine_ip")
private String machineIp;
#Column(name = "data_center")
private String dataCenter;
#Column(name = "description")
private String description;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
#JoinColumns({#JoinColumn(name = "ref_id", referencedColumnName = "ref_id"),
#JoinColumn(name = "revision", referencedColumnName = "revision")})
private Job job;
}
Here is the code that persist the entity
#Service
public class QReaderService {
#Autowired
private JobRepository jobRepository;
#Autowired
private TaskRepository taskRepository;
public boolean addJob(Job job) {
Job previousJob = jobRepository.findByJobRefId(job.getRefId());
if (previousJob == null) {
**jobRepository.save(job);**
return true;
} else {
switch (job.getStatus()) {
case FAILED:
case EXCEPTION:
int revision = 0;
revision += previousJob.getRevision();
previousJob.setStatus(Status.FAILED);
jobRepository.save(previousJob);
break;
}
}
return true;
}
}
This is how i build the job entity
Job job = new Job();
job.setRefId("f78d9as7f98dsa7f97a97f98sda9f7");
job.setAppName("appname");
job.setLocale("locale");
job.setPlatform("platform");
job.setCategory("category");
job.setReleaseVersion("1.1");
job.setStatus(Status.PROCESSING);
job.setAuthor("author");
job.setFunctional("functional");
job.setJobStartDate(new Date());
job.setVersion("1.1");
job.setTier("tier1");
job.setVendor("vendor");
Task task = new Task();
task.setDescription("description");
task.setDataCenter("dataCenter");
task.setStartTime(new Date());
task.setStatus(Status.PROCESSING);
task.setMachineIp("ip");
task.setModuleName("module");
job.setTasks(new ArrayList<Task>(Arrays.asList(task)));
jobRepository.save(job);
To persist child entities when you call save on parent entity, both sides of the relations should be set.
job.setTasks(job.setTasks(new ArrayList<Task>(Arrays.asList(task)));
//Missing line //Important for persistence of child
task.setJob(job);
Hope this helps.

Categories