Unable to fetch the data from the database when tables are mapped by many to many - spring-boot

I am unable to fetch the users data from the database, and I also wonder how to handle the rest request in many to many cases for the same scenario.
I am using Spring Boot and Spring Data JPA. My code for the database is below:
CREATE TABLE `m3_group` (
`GROUP_ID` bigint(11) NOT NULL AUTO_INCREMENT,
`GROUP_NAME` varchar(30) DEFAULT NULL,
`GROUP_CREATED_DATE` datetime DEFAULT NULL,
`GROUP_ADMIN` varchar(14) DEFAULT NULL,
PRIMARY KEY (`GROUP_ID`)
)
ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE `m3_user` (
`USER_ID` bigint(11) NOT NULL AUTO_INCREMENT,
`USER_NAME` varchar(50) DEFAULT NULL,
PRIMARY KEY (`USER_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=330 DEFAULT CHARSET=utf8;
CREATE TABLE `m3_user_group` (
`GROUP_USER_ID` bigint(11) DEFAULT NULL,
`GROUP_ID` bigint(11) DEFAULT NULL,
KEY `FK1_GROUP_ID` (`GROUP_ID`),
KEY `FK2_USER_ID` (`GROUP_USER_ID`),
CONSTRAINT `FK1_GROUP_ID` FOREIGN KEY (`GROUP_ID`) REFERENCES `m3_group` (`GROUP_ID`),
CONSTRAINT `FK2_USER_ID` FOREIGN KEY (`GROUP_USER_ID`) REFERENCES `m3_user` (`USER_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#Entity
#Table(name = "M3_USER")
public class User implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "USER_ID")
private long userId;
#NotBlank
#Column(name = "USER_NAME")
private String userName;
//many-to-many
#ManyToMany(mappedBy="listOfUsers",fetch=FetchType.EAGER)
private List<Group> listOfGroup=new ArrayList<Group>();
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public List<Group> getListOfGroup() {
return listOfGroup;
}
public void setListOfGroup(List<Group> listOfGroup) {
this.listOfGroup = listOfGroup;
}
}
#Entity
#Table(name="M3_GROUP")
public class Group implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="GROUP_ID")
private long groupId;
#Column(name="GROUP_NAME")
private String groupName;
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
#Column(name="GROUP_CREATED_DATE")
#JsonFormat(locale = "en-IN", shape = JsonFormat.Shape.STRING, pattern =
"yyyy-MM-dd HH:mm", timezone = "GMT+5:30")
private Date groupCreatedDate;
#Column(name="GROUP_ADMIN")
private String groupAdminMobileNumber;
//many-to-many
#ManyToMany(fetch=FetchType.EAGER)
#JoinTable(name = "M3_USER_GROUP", joinColumns = #JoinColumn(name =
"GROUP_USER_ID") , inverseJoinColumns = #JoinColumn(name = "GROUP_ID") )
private List<User> listOfUsers=new ArrayList<User>();
public long getGroupId() {
return groupId;
}
public void setGroupId(long groupId) {
this.groupId = groupId;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public Date getGroupCreatedDate() {
return groupCreatedDate;
}
public void setGroupCreatedDate(Date groupCreatedDate) {
this.groupCreatedDate = groupCreatedDate;
}
public String getGroupAdminMobileNumber() {
return groupAdminMobileNumber;
}
public void setGroupAdminMobileNumber(String groupAdminMobileNumber) {
this.groupAdminMobileNumber = groupAdminMobileNumber;
}
public List<User> getListOfUsers() {
return listOfUsers;
}
public void setListOfUsers(List<User> listOfUsers) {
this.listOfUsers = listOfUsers;
}
}
#Repository
public interface GroupRepository extends JpaRepository<Group, Long> {
List<Group> findByGroupId(long groupid);
}
#RestController
public class GroupController
{
#Autowired
GroupRepository groupRepository;
#RequestMapping(value="/find/{groupId}",method=RequestMethod.POST)
public ResponseEntity<List<Group>> find(#PathVariable String groupId)
{
long id=Long.parseLong(groupId);
List<Group> group = groupRepository.findByGroupId(id);
System.out.println(group.toString());
return new ResponseEntity<List<Group>>(group,HttpStatus.OK);
}
}
I have mapped the user and group table with many to many bidirectional and i am trying to fetch the data i.e users associated with the groupId but listOfUsers is showing empty.
My rest request is:
Http ://localhost:5000/find/1
And the response is:
[
{
"groupId": 1,
"groupName": "Om namo raghavendra",
"groupCreatedDate": "2017-05-17 12:48",
"groupAdminMobileNumber": "917676060664",
"listOfUsers":[
]
}
]
listOfUsers is empty, so I want to users by using groupId.

Related

I'm trying to implement group by on a table and want to implement it from repository

I've a table tbl_rating, I'm trying to get avg o=rating of the users that are existing in this table.
This is the table I have.
CREATE TABLE `tbl_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`email` varchar(255) NOT NULL,
`contact` varchar(255) NOT NULL,
`status` enum('active','inactive') NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `contact` (`contact`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1
this is the tbl_rating
CREATE TABLE `tbl_rating` (
`id` bigint(255) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`point` int(1) NOT NULL,
`status` enum('active','inactive') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
this is the query that I'm trying to implement from repository.
SELECT r.user_id, u.name, AVG(r.point) AS average
FROM tbl_rating r LEFT JOIN tbl_user u ON u.id=r.user_id
GROUP BY r.user_id;
this is my controller
#RequestMapping(value = "/user/rating/avg/individual", method = RequestMethod.POST)
public JsonNode getAvgRatingOfIndividual(HttpServletRequest httpServletRequest) throws IOException {
JSONArray response = new JSONArray();
List<Rating> ratings = new ArrayList<>();
try {
ratings = ratingService.getAvgRatingOfIndividual();
if (ratings.size() > 0) {
} else {
response = new JSONArray();
}
} catch (Exception e) {
return objectMapper.readTree(utility.createResponse(500, KeyWord.ERROR, e.toString()).toString());
}
return objectMapper.readTree(response.toString());
}
following are the service and repository where I'm stuck
service
public List<Rating> getAvgRatingOfIndividual() {
return ratingRepository.??
}
repository
#Repository
public interface RatingRepository extends JpaRepository<Rating, Long> {
}
rating model
#Entity
#Table(name = "tbl_rating")
public class Rating {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
long id;
#ManyToOne
#JoinColumn(name = "user_id")
User user;
#Column(name = "point")
int point;
#Column(name = "status")
String status;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getPoint() {
return point;
}
public void setPoint(int point) {
this.point = point;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
user model
#Entity
#Table(name = "tbl_user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
long id;
#Column(name = "name")
String name;
#Column(name = "email")
String email;
#Column(name = "contact")
String contact;
#Column(name = "status")
String status;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
}
would appreciate if i could get any sort of help on this native query writing in spring boot repository
You can use from a DTO and fill it implicitly in repository.
package com.test.dto;
#Value
public class RatingDTO{
private Long userId;
private String name;
private Double average;
}
And in the repository class:
//RatingRepository.java
#Repository
public interface RatingRepository extends JpaRepository<Rating, Long> {
#Query("SELECT new com.test.dto.RatingDTO(R.user.id, R.user.name, AVG(R.point)) FROM Rating R GROUP BY R.user.id")
List<RatingDTO> getAveragePoints();
}

how can I find last 7 days data using spring data JPA?

I want to find last 7 orders form order table, how am I supposed to do that?
Here's the order table
CREATE TABLE `orders` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`total` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`service_charge` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`vat` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`delivery_charge` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`subtotal` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`point_used` int(5) DEFAULT NULL,
`discount_id` bigint(20) DEFAULT NULL,
`user_id` bigint(20) NOT NULL,
`address_id` bigint(20) NOT NULL,
`payement_type` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`payment_status` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`message` mediumtext COLLATE utf8mb4_unicode_ci,
`transaction_id` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`invoice` enum('yes','no') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'no',
`status` enum('pending','accepted','processed','on-way','delivered','cancelled') COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `address_id` (`address_id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
this is the service I'm using
public List<Order> getLastSevenDaysOrders(User user, String todayString, String sevenDaysBeforeString) {
ArrayList<Order> orders = new ArrayList<>();
orderRepository.findByUserAndCreatedAtBetween(user, todayString, sevenDaysBeforeString).forEach(orders::add);
return orders;
}
This is the repository I've.
List<Order> findByUserAndCreatedAtBetween(User user, String todayString, String sevenDaysBeforeString);
This is my controller
#RequestMapping(value = "/order/recent", method = RequestMethod.POST)
public JsonNode getRecentOrder(HttpServletRequest httpServletRequest, #RequestBody String userId) throws IOException {
long startTime = System.currentTimeMillis();
utility.printCallingUrl(httpServletRequest);
JSONObject request = new JSONObject(userId);
JSONArray response = new JSONArray();
//Order order = new Order();
List<Order> orders = new ArrayList<>();
String auth = httpServletRequest.getHeader("Authorization");
String authentication = utility.getBasicAuth();
if (auth.equals(authentication)) {
try {
Calendar calendar = Calendar.getInstance();
String pattern = "yyyy-MM-dd HH:mm:ss";
DateFormat dateFormat = new SimpleDateFormat(pattern);
Date today = calendar.getTime();
String todayString = dateFormat.format(today);
calendar.add(Calendar.DAY_OF_MONTH, -7);
Date sevenDaysBefore = calendar.getTime();
String sevenDaysBeforeString = dateFormat.format(sevenDaysBefore);
User user = userService.getUser(request.getLong("user_id"));
orders = orderService.getLastSevenDaysOrders(user, todayString, sevenDaysBeforeString);
if (orders.size() > 0) {
for (Order order : orders) {
JSONObject response2 = new JSONObject();
response2.put("receiversName", order.getAddress().getReceiversName());
response2.put("address", order.getAddress().getAddress());
response2.put("nearbyLandmark", order.getAddress().getNearbyLandmark());
response2.put("receiversContact", order.getAddress().getReceiversContact());
response2.put("district", order.getAddress().getDistrict().getNameBn());
response2.put("division", order.getAddress().getDivision().getNameBn());
response2.put("village", order.getAddress().getVillage());
response2.put("name", order.getUser().getName());
response2.put("userId", order.getUser().getId());
response2.put("upazilla", order.getAddress().getUpazilla().getNameBn());
response2.put("vat", order.getVat());
response2.put("deliveryCharge", order.getDeliveryCharge());
response2.put("discountAmount", order.getDiscount().getAmount());
response2.put("discountCode", order.getDiscount().getCode());
response2.put("discountName", order.getDiscount().getName());
response2.put("discountId", order.getDiscount().getId());
response2.put("pointUsed", order.getPointUsed());
response2.put("message", order.getMessage());
response2.put("transactionId", order.getTransactionId());
response2.put("createdAt", order.getCreatedAt());
response2.put("total", order.getTotal());
response2.put("serviceCharge", order.getServiceCharge());
response2.put("subtotal", order.getSubtotal());
response2.put("orderId", order.getId());
response2.put("invoice", order.getInvoice());
response2.put("contact", order.getUser().getContact());
response2.put("payementType", order.getPayementType());
response2.put("paymentStatus", order.getPaymentStatus());
response2.put("status", order.getStatus());
response.put(response2);
}
Log log = utility.saveLog(KeyWord.GET_ORDERS, KeyWord.CMS, httpServletRequest, "200", request, new JSONObject().put("data", response), startTime);
if (log != null) {
utility.showMessage("Log inserted successfully with ID " + log.getId());
} else {
utility.showMessage("Log not inserted");
}
} else {
response = new JSONArray();
Log log = utility.saveLog(KeyWord.GET_ORDERS, KeyWord.CMS, httpServletRequest, "500", request, new JSONObject().put("data", response), startTime);
if (log != null) {
utility.showMessage("Log inserted successfully with ID " + log.getId());
} else {
utility.showMessage("Log not inserted");
}
}
} catch (Exception e) {
utility.showMessage(e.toString());
return mapper.readTree(utility.createResponse(500, KeyWord.ERROR, e.toString()).toString());
}
} else {
return mapper.readTree(utility.createResponse(500, KeyWord.ERROR, KeyWord.AUTHENTICATION).toString());
}
return mapper.readTree(response.toString());
}
Order model
#Entity
#Table(name = "orders")
public class Order {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
#Expose
private long id;
#Column(name = "total")
#Expose
private String total;
#Column(name = "service_charge")
#Expose
private String serviceCharge;
#Column(name = "vat")
#Expose
private String vat;
#Column(name = "delivery_charge")
#Expose
private String deliveryCharge;
#Column(name = "subtotal")
#Expose
private String subtotal;
#Column(name = "point_used")
#Expose
private int pointUsed;
// #Column(name = "discount_id")
// private long discountId;
#ManyToOne
#JoinColumn(name = "discount_id")
#Expose
Discount discount;
#ManyToOne
#Expose
User user;
#OneToOne
#Expose
Address address;
#Column(name = "payement_type")
#Expose
private String payementType;
#Column(name = "payment_status")
#Expose
private String paymentStatus;
#Column(name = "message")
#Expose
private String message;
#Column(name = "transaction_id")
#Expose
private String transactionId;
#Column(name = "invoice")
#Expose
private String invoice;
#Column(name = "status")
#Expose
private String status;
#Column(name = "created_at")
#Expose
private String createdAt;
#Column(name = "updated_at")
#Expose
private String updatedAt;
public Order() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTotal() {
return total;
}
public void setTotal(String total) {
this.total = total;
}
public String getVat() {
return vat;
}
public void setVat(String vat) {
this.vat = vat;
}
public String getServiceCharge() {
return serviceCharge;
}
public void setServiceCharge(String serviceCharge) {
this.serviceCharge = serviceCharge;
}
public String getDeliveryCharge() {
return deliveryCharge;
}
public void setDeliveryCharge(String deliveryCharge) {
this.deliveryCharge = deliveryCharge;
}
public String getSubtotal() {
return subtotal;
}
public void setSubtotal(String subtotal) {
this.subtotal = subtotal;
}
public int getPointUsed() {
return pointUsed;
}
public void setPointUsed(int pointUsed) {
this.pointUsed = pointUsed;
}
public Discount getDiscount() {
return discount;
}
public void setDiscount(Discount discount) {
this.discount = discount;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getPayementType() {
return payementType;
}
public void setPayementType(String payementType) {
this.payementType = payementType;
}
public String getPaymentStatus() {
return paymentStatus;
}
public void setPaymentStatus(String paymentStatus) {
this.paymentStatus = paymentStatus;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
public String getInvoice() {
return invoice;
}
public void setInvoice(String invoice) {
this.invoice = invoice;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(String updatedAt) {
this.updatedAt = updatedAt;
}
}
Order Repository
#Repository
public interface OrderRepository extends PagingAndSortingRepository<Order, Long> {
List<Order> findByUserAndCreatedAtBetween(User user, String todayString, String sevenDaysBeforeString);
}
What am I doing wrong in service while writing method for repository?
I'm getting a blank array. I think I'm doing something wrong when writing findByUserAndCreatedAtBetween. would be great if could get any suggestion.
Your contract
List<Order> findByUserAndCreatedAtBetween(User user, String todayString, String sevenDaysBeforeString);
gets date-parameters as a string. It's wrong. Spring JPA works fine with Date.
// Repository
List<Order> findByUserAndCreatedAtBetween(User user, Date today, String Date sevenDaysBefore);
// Service
public List<Order> getLastSevenDaysOrders(User user, Date today, Date sevenDaysBefore) {
return orderRepository.findByUserAndCreatedAtBetween(user, today, sevenDaysBefore);
}
And then
Calendar calendar = Calendar.getInstance();
Date today = calendar.getTime();
calendar.add(Calendar.DAY_OF_MONTH, -7);
Date sevenDaysBefore = calendar.getTime();
User user = userService.getUser(request.getLong("user_id"));
orders = orderService.getLastSevenDaysOrders(user, today, sevenDaysBefore);

Hibernate didn't create one of tables

I'm learning spring..., I build a simple application.
I have a problem because hibernate does not want to generate one of the models..
I do not know what's wrong
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.io.Serializable;
#Entity
#Table(name="access_card")
public class AccessCard implements Serializable{
private static final long serialVersionUID = -4015209774835055079L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
private Long id;
#Column(name="key")
private String key;
#Column(name="enabled")
private Boolean enabled;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id", nullable = false)
#JsonIgnore
private User user;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Other classes are written similarly and everything works.
Error:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error
executing DDL "create table access_card (id bigint not null, enabled
bit, key varchar(255), user_id bigint not null, primary key (id))
engine=MyISAM" via JDBC Statement
And properties
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
Follow your comment, The problem pointed out at here
key varchar(255)
The table name is reserved keyword.
See https://hibernate.atlassian.net/browse/HHH-4453
If you still want it, the solution is https://vladmihalcea.com/escape-sql-reserved-keywords-jpa-hibernate/

Spring - Hibernate ManyToMany in Restful app

i have my spring app running with two entities Article and Category.
I integrated RestResponses and it works all fine. Next i added a ManyToMany Relationship to these entities and my rest responses return 404.
I will show you my configuration:
DROP TABLE IF EXISTS `articles`;
create table `articles` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;
DROP TABLE IF EXISTS `categories`;
create table `categories` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;
DROP TABLE IF EXISTS `categories_articles`;
CREATE TABLE IF NOT EXISTS `categories_articles` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`categoryID` int(11) UNSIGNED NOT NULL,
`articleID` int(11) UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `categoryArticleID` (`categoryID`, `articleID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;
ALTER TABLE `categories_articles`
ADD CONSTRAINT `categories_articles_fk_1` FOREIGN KEY (`categoryID`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `categories_articles_fk_2` FOREIGN KEY (`articleID`) REFERENCES `articles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
Article.java:
#Entity
#Table(name = "articles")
public class Article {
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="name")
private String name;
private List<Category> categories = new ArrayList<Category>();
public Article() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#ManyToMany(mappedBy = "articles")
public List<Category> getCategories() {
return categories;
}
public void setCategories(List<Category> categories) {
this.categories = categories;
}
}
Category.java:
#Entity
#Table(name = "categories")
public class Category {
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="name")
private String name;
private List<Article> articles = new ArrayList<Article>();
public Category() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(
name = "categories_articles",
joinColumns = #JoinColumn(name = "categoryID", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "articleID", referencedColumnName = "id"))
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
}
And my RestController:
#GetMapping("/rest/categories")
public RestResponse<Category> list() {
List<Category> data = categoryService.list();
RestResponse<Category> restResponse = new RestResponse<Category>(true, data.size(), data);
return restResponse;
}
where RestResponse is just a simple PoJo:
public class RestResponse<T> {
private Boolean success;
private Integer count;
private List<T> data;
public RestResponse(Boolean success, Integer count, List<T> data) {
this.success = success;
this.count = count;
this.data = data;
}
// getters and setters
}
Sooo, as soon as i comment the many-to-many part and load my app, it all works fine.. but when i uncomment the many-to-many part, i get 404..
I have no idea why, could anybody help me with this issue?
thanks and greetings!

1 to1 relationship causing , Exception :org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

Technologies used: Spring MVC , Hibernate , MySQL DB, Windows 7, NetBeans IDE
My create,read,update operations, work however Im getting an Exception when trying to delete UserAccount & associated password record:
SEVERE: Cannot delete or update a parent row: a foreign key constraint fails (profiler.password, CONSTRAINT FK4C641EBBCF6D23F4 FOREIGN KEY (user_id) REFERENCES user_account (user_id))
Oct 10, 2012 11:52:22 AM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (profiler.password, CONSTRAINT FK4C641EBBCF6D23F4 FOREIGN KEY (user_id) REFERENCES user_account (user_id))
UserAccount & Password relationship:
UserAccount class:
package com.profile.beans;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import javax.persistence.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
#Entity
#Table(name = "user_account")
public class UserAccount implements Serializable {
#Autowired
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "user_account_seq")
#SequenceGenerator(name = "user_account_seq", sequenceName = "user_account_seq")
#Column(name = "user_id")
private Long userId ;
//
#Autowired
#Column(name = "user_name")
private String userName;
//
#Autowired
#Column(name = "user_type")
private String userType;
//
#Autowired
#Column(name = "first_name")
private String firstName;
//
#Autowired
#Column(name = "last_name")
private String lastName;
//
#Autowired
#Column(name = "email")
private String email;
//
#Autowired
#Column(name = "phone_contact")
private String phoneContact;
//
#Autowired
#Column(name = "address")
private String address;
//
#Autowired
#Column(name = "city")
private String city ;
//
#Autowired
#Column(name = "state")
private String state;
//
#Autowired
#Column(name = "country")
private String country;
//
#Autowired
#Column(name = "zipcode")
private Integer zipcode = 0;
//is the user account Active either due to user deactivation,admin deactivation, or nonpayment
#Autowired
#Column(name = "active")
private boolean active = false;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "UserAccount")
#JoinColumn(name="user_id")
private Password Password = null;
#OneToMany(mappedBy="UserAccount",cascade={CascadeType.ALL})
#JoinColumn(name="doc_id")
private List<Document> documents = null;
#Autowired(required = false)
public UserAccount() {
}
#Autowired(required = true)
public UserAccount(Long userId, String userName, String userType, String firstName, String lastName, String email, String phoneContact, String address, String city, String state, String country, Integer zipcode) {
this.userId = userId;
this.userName = userName;
this.userType = userType;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.phoneContact = phoneContact;
this.address = address;
this.city = city;
this.state = state;
this.country = country;
this.zipcode = zipcode;
}
public com.profile.beans.Password getPassword() {
return Password;
}
public void setPassword(com.profile.beans.Password Password) {
this.Password = Password;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Document> getDocuments() {
return documents;
}
public void setDocuments(List<Document> documents) {
this.documents = documents;
}
public Integer getZipcode() {
return zipcode;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhoneContact() {
return phoneContact;
}
public void setPhoneContact(String phoneContact) {
this.phoneContact = phoneContact;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public void setZipcode(Integer zipcode) {
try
{
this.zipcode = zipcode;
}
catch (NumberFormatException exc)
{
exc.printStackTrace();
}
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final UserAccount other = (UserAccount) obj;
if ((this.userId == null) ? (other.userId != null) : !this.userId.equals(other.userId)) {
return false;
}
return true;
}
#Override
public int hashCode() {
int hash = 3;
hash = 73 * hash + (this.userId != null ? this.userId.hashCode() : 0);
return hash;
}
#Override
public String toString() {
return "UserAccount{" + "userId=" + userId + ", userName=" + userName + ", userType=" + userType + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + ", phoneContact=" + phoneContact + ", address=" + address + ", city=" + city + ", state=" + state + ", country=" + country + ", zipcode=" + zipcode + ", active=" + active + ", documents=" + documents + '}';
}
}
Password class :
package com.profile.beans;
import java.io.Serializable;
import javax.persistence.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.hibernate.annotations.Cascade;
#Entity
#Table(name = "Password")
public class Password implements Serializable {
#Autowired(required = false)
public Password() {
}
#Autowired(required = true)
public Password(UserAccount UserAccount) {
this.UserAccount = UserAccount;
}
#Autowired
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "password_seq")
#SequenceGenerator(name = "password_seq", sequenceName = "password_seq")
#Column(name = "password_id")
private Long passwordId;
#Autowired
#Column(name = "password")
private String password = null;
//1 to 1 relation with UserAccounts
//1 to 1 relation with UserAccounts
#Autowired
#Qualifier("UserAccount")
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "user_id", referencedColumnName="user_id",nullable = false)
private UserAccount UserAccount;
#Autowired(required = true)
public Password(UserAccount UserAccount, String password) {
this.UserAccount = UserAccount;
this.password = password;
}
public UserAccount getUserAccount() {
return UserAccount;
}
public void setUserAccount(UserAccount UserAccount) {
this.UserAccount = UserAccount;
}
public Long getPasswordId() {
return passwordId;
}
public void setPasswordId(Long passwordId) {
this.passwordId = passwordId;
}
public String getPassword() {
return password;
}
}
My database DDL (MySQL syntax):
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
DROP SCHEMA IF EXISTS `profiler`;
CREATE SCHEMA IF NOT EXISTS `profiler` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
DROP SCHEMA IF EXISTS `profiler` ;
CREATE SCHEMA IF NOT EXISTS `profiler` DEFAULT CHARACTER SET latin1 ;
USE `profiler` ;
-- -----------------------------------------------------
-- Table `profiler`.`user_account`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `profiler`.`user_account` ;
CREATE TABLE IF NOT EXISTS `profiler`.`user_account` (
`user_id` BIGINT(20) NOT NULL ,
`user_name` VARCHAR(45) NULL DEFAULT NULL ,
`user_type` VARCHAR(45) NULL DEFAULT NULL ,
`first_name` VARCHAR(45) NULL DEFAULT NULL ,
`last_name` VARCHAR(45) NULL DEFAULT NULL ,
`email` VARCHAR(45) NULL DEFAULT NULL ,
`phone_contact` VARCHAR(45) NULL DEFAULT NULL ,
`address` VARCHAR(45) NULL DEFAULT NULL ,
`city` VARCHAR(45) NULL DEFAULT NULL ,
`state` VARCHAR(45) NULL DEFAULT NULL ,
`country` VARCHAR(45) NULL DEFAULT NULL ,
`zipcode` VARCHAR(45) NULL DEFAULT NULL ,
`active` TINYINT(1) NULL DEFAULT NULL ,
PRIMARY KEY (`user_id`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;
-- -----------------------------------------------------
-- Table `profiler`.`document`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `profiler`.`document` ;
CREATE TABLE IF NOT EXISTS `profiler`.`document` (
`doc_id` BIGINT(20) NOT NULL ,
`title` VARCHAR(45) NULL DEFAULT NULL ,
`format` VARCHAR(45) NULL DEFAULT NULL ,
`url_string` VARCHAR(45) NULL DEFAULT NULL ,
`size_in_bytes` INT(11) NULL DEFAULT NULL ,
`created_on` TIMESTAMP NULL DEFAULT NULL ,
`bytes` BLOB NULL DEFAULT NULL ,
`height` INT(11) NULL DEFAULT NULL ,
`width` INT(11) NULL DEFAULT NULL ,
`user_id` BIGINT(20) NOT NULL ,
PRIMARY KEY (`doc_id`) ,
CONSTRAINT `user_id_fk`
FOREIGN KEY (`user_id` )
REFERENCES `profiler`.`user_account` (`user_id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;
-- -----------------------------------------------------
-- Table `profiler`.`password`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `profiler`.`password` ;
CREATE TABLE IF NOT EXISTS `profiler`.`password` (
`password_id` BIGINT(20) NOT NULL ,
`password` VARCHAR(45) NOT NULL ,
`user_id` BIGINT(20) NOT NULL ,
PRIMARY KEY (`password_id`) ,
CONSTRAINT `user_id_fk_1`
FOREIGN KEY (`user_id` )
REFERENCES `profiler`.`user_account` (`user_id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;
CREATE INDEX `user_id_fk_idx` ON `profiler`.`password` (`user_id` ASC) ;
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
SET foreign_key_checks = 1;
UserAccount controller class:
#Controller
#RequestMapping("/UserAccount")
public class UserAccountController {
#Autowired
private UserAccountDao userAccountDao;
#Autowired
private PasswordDao passwordDao;
public UserAccountController() {
}
public UserAccountController(UserAccountDao userAccountDao, PasswordDao passwordDao) {
this.userAccountDao = userAccountDao;
this.passwordDao = passwordDao;
}
#RequestMapping(value="/Register")
public String RegisterationView()
{
return "UserAccount/Register";
}
#RequestMapping(value="/Login")
public String LoginView()
{
return "UserAccount/Login";
}
#RequestMapping(value="/Update")
public String UpdateView()
{
return "UserAccount/Update";
}
//create
#RequestMapping(value="/create",method = RequestMethod.POST)
public String create(
#RequestParam("username") String username,
#RequestParam("email") String email,
#RequestParam("firstname") String firstName,
#RequestParam("lastname") String lastName,
#RequestParam("phonecontact") String phonecontact,
#RequestParam("address") String address,
#RequestParam("state") String state,
#RequestParam("city") String city,
#RequestParam("country") String country,
#RequestParam("password") String password,
#RequestParam("zipcode") Integer zipcode,
HttpSession session,HttpServletRequest request, Model model)
{
String view = null ;
//*check if username exists
//*if email exists
UserAccount userAccount = new UserAccount();
userAccount.setAddress(address);
userAccount.setCity(city);
userAccount.setCountry(country);
userAccount.setState(state);
userAccount.setPhoneContact(phonecontact);
userAccount.setEmail(email);
userAccount.setZipcode(zipcode);
userAccount.setFirstName(firstName);
userAccount.setLastName(lastName);
userAccount.setUserName(username);
userAccount.setUserType(utility.UserTypes.REGULAR);
//instatiate password
//**password not exist before & must be at least characters long
Password userPassword = new Password(userAccount,password);
userAccountDao.create(userAccount);
passwordDao.create(userPassword);
//add userAccount to model
model.addAttribute("userAccount", userAccount);
session.setAttribute("userAccount", userAccount);
view = "UserAccount/UserMainMenu";
return view;
}
//update
#RequestMapping(value="/update",method = RequestMethod.GET)
public String update( #RequestParam(value="username", required=false) String username,
#RequestParam(value="email",required=false) String email,
#RequestParam(value="firstname",required=false) String firstName,
#RequestParam(value="lastname",required=false) String lastName,
#RequestParam(value="phonecontact",required=false) String phonecontact,
#RequestParam(value="address",required=false) String address,
#RequestParam(value="state",required=false) String state,
#RequestParam(value="city",required=false) String city,
#RequestParam(value="country",required=false) String country,
#RequestParam(value="zipcode",required=false) Integer zipcode,#RequestParam(value="update",required=false) String update,HttpSession session,HttpServletRequest request)
{
String view = null ;
UserAccount userAccount = (UserAccount)session.getAttribute("userAccount");
//*check if username exists
//*if email exists
try
{
System.out.println("Class UserAccountController, update:" + update);
if (update.equalsIgnoreCase("update"))
{
//reset values in case updated info
userAccount.setAddress(address);
userAccount.setCity(city);
userAccount.setCountry(country);
userAccount.setState(state);
userAccount.setPhoneContact(phonecontact);
userAccount.setEmail(email);
userAccount.setZipcode(zipcode);
userAccount.setFirstName(firstName);
userAccount.setLastName(lastName);
userAccount.setUserName(username);
userAccount.setUserType(utility.UserTypes.REGULAR);
//instatiate password
userAccountDao.update(userAccount);
//add userAccount to model
session.setAttribute("userAccount", userAccount);
view = "UserAccount/UserMainMenu";
}
if (update.equalsIgnoreCase("delete"))
{
System.out.println("Class UserAccountController, userAccount: "+userAccount);
//query for password that corresponds to particular user
Password password = (Password)passwordDao.getByUserAccount(userAccount);
System.out.println("Class UserAccountController, password: "+password );
password.setUserAccount(null);
//delete password
passwordDao.delete(password);
//delete user account
userAccountDao.delete(userAccount);
session.removeAttribute("userAccount");
view = "UserAccount/UserMainMenu";
}
}
catch (Exception exc)
{
//forward to error page
exc.getMessage();
view = "error";
}
return view;
}
//delete
#RequestMapping(value="/delete",method = RequestMethod.DELETE)
public String delete( #RequestParam("id")Long id,HttpSession session,HttpServletRequest request)
{
String view = null ;
UserAccount newUserAccount = userAccountDao.getById(id);
userAccountDao.delete(newUserAccount);
view = "UserAccount/UserMainMenu";
return view;
}
//read
#RequestMapping(value="/read",method = RequestMethod.GET)
public void read(Long id)
{
userAccountDao.getById(id);
}
public UserAccountDao getUserAccountDao() {
return userAccountDao;
}
public void setUserAccountDao(UserAccountDao userAccountDao) {
this.userAccountDao = userAccountDao;
}
public PasswordDao getPasswordDaoImpl() {
return passwordDao;
}
public void setPasswordDaoImpl(PasswordDaoImpl passwordDao) {
this.passwordDao = passwordDao;
}
}
PasswordDaoImpl class:
#Repository
#Transactional
public class PasswordDaoImpl implements PasswordDao{
#Autowired
private SessionFactory sessionFactory;
private Session currentSession()
{
return sessionFactory.getCurrentSession();
}
#Override
public Password getByUserAccount(UserAccount UserAccount) {
String hql = "FROM com.profile.beans.Password WHERE Password.UserAccount.UserId =:id";
Long id = UserAccount.getUserId();
Query q = currentSession().createQuery(hql);
return (Password)q.setParameter("id",id).list().get(0);
}
#Override
public void create(Password Password) {
currentSession().save(Password);
}
#Override
public void delete(Password Password) {
currentSession().delete(Password);
}
#Override
public void update(Password Password) {
currentSession().update(Password);
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
You should break the relationship before you delete UserAccount:
Password pass = userAccount.getPassword();
userAccount.setPassword(null);
userAccountDao.delete(pass);
userAccountDao.delete(userAccount);

Resources