I'm setting an API endpoint that updates an existing user detail, to do that I try to fetch an existing user from the database by id, when I start the application and test with postman it runs the query on my console but displays TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing and fails to make the intended updates. Here is my code
Member
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name ="member",
indexes = {
#Index(
columnList = "email_address",
name = "email_address_idx",
unique = true
),
},
uniqueConstraints = {
#UniqueConstraint(
columnNames = {"email_address", "phone_number"},
name = "email_address_phone_number_uq"
)
}
)
public class Member {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "first_name", nullable = false)
private String firstName;
#Column(name = "last_name", nullable = false)
private String lastName;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "nationality_id")
private Country nationality;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "country_of_residence_id")
private Country countryOfResidence;
#Temporal(TemporalType.DATE)
#Column(name ="date_of_birth")
private Date dateOfBirth = new Date();
#Column(name ="current_job_title")
private String currentJobTitle;
#Column(name = "email_address", nullable = false)
private String emailAddress;
#Column(name = "username")
private String username;
#Column(name ="phone_number")
private String phoneNumber;
#Column(name ="city")
private String city;
#Column(name ="state")
private String state;
#Column(name ="password", nullable = false)
private String password;
#Column(name ="avatar")
private String avatar;
#Column(name ="active", nullable = false)
private Boolean active = true;
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "created_on", updatable = false, nullable = false)
private Date createdOn;
#UpdateTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updated_on", nullable = false)
private Date updatedOn;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(
name = "member_roles",
joinColumns = #JoinColumn(
name = "member_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(
name = "role_id", referencedColumnName = "id")
)
private Set<Role> roles = new HashSet<>();
public void addRole(Role role) {
this.getRoles().add(role);
}
public void clearRoles() {
this.roles = new HashSet<>();
}
}
MemberDto
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
public class UpdateMemberDto {
#NotNull(message = "{member.first_name.notNull}")
private String firstName;
#NotNull(message = "{member.last_name.notNull}")
private String lastName;
private Date dateOfBirth;
private String currentJobTitle;
#NotNull(message = "{member.email_address.notNull}")
private String emailAddress;
private String username;
#NotNull(message = "{member.phone_number.notNull}")
private String phoneNumber;
private String city;
private String state;
private String password;
private String avatar;
private Boolean active;
}
ServiceImpl
#Slf4j
#Service
public class UpdateMemberServiceImpl implements UpdateMemberService {
#Autowired
private ModelMapper modelMapper;
private final UpdateMemberRepository repository;
private final MemberJpaRepository jpaRepository;
public UpdateMemberServiceImpl(UpdateMemberRepository repository, MemberJpaRepository jpaRepository) {
this.repository = repository;
this.jpaRepository = jpaRepository;
}
#Override
#Transactional
public Member update(Long id, UpdateMemberDto body) {
Optional<Member> existingMember = jpaRepository.findById(id);
if (existingMember != null) {
Member member = new Member();
member = modelMapper.map(body, Member.class);
member.setId(id);
member = jpaRepository.save(member);
return member;
}
throw new MemberNotFoundException(id);
}
}
Related
Trying to run a delete query on a many-one relationship. But sometime it's stuck for a while when the count of row delete is more then ~50.
Repository:
#Repository
public interface TransitItemRepository extends JpaRepository<TransitItemsMapping, UUID> {
#Modifying
#Transactional
#Query(value="delete from TransitItemsMapping t where t.grouping_form_id=:groupingFormId",nativeQuery = true)
void deleteByGroupingFormId(#Param("groupingFormId") UUID groupingFormId);
}
Domain:TransitItemsMapping.java
#Data
#Entity
#Table(name = "TransitItemsMapping")
public class TransitItemsMapping implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
#GeneratedValue(generator = "uuid")
#Column(name = "transit_Item_id",unique = true, nullable = false)
private UUID transitItemId;
#ToString.Exclude
#JsonManagedReference
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "grouping_form_id")
//#OnDelete(action = OnDeleteAction.CASCADE)
private GroupingForm groupingForm;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(referencedColumnName = "dim_Item_ID",name = "item_id")
private Item item;
#Column(name ="item_relationship_id", insertable = false,updatable = false)
private String itemRelationshipId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "item_relationship_id",referencedColumnName = "dim_item_relationship_id")
private VendorFactoryItem vendorFactoryItem;
#Column(name = "edam_id")
private String edamId;
#Column(name = "model_number")
private String modelNumber;
#Column(name = "description")
private String description;
#Column(name = "packaging_details")
private String packagingDetails;
#Column(name = "packaging_method")
private String packagingMethod;
#Column(name = "is_side_stack")
private String isSideStack;
#Column(name = "quantity")
private Integer quantity;
#Column(name = "dimensions")
private String dimensions;
#Column(name = "product_net_weight")
private String productNetWeight;
#Column(name = "plastic_bag_ind")
private String plasticBagInd;
#Column(name = "insertion_order")
private Integer insertionOrder;
#Column(name = "comments")
private String comments;
#Column(name = "item_unique_id")
private String itemUniqueId;
#Column(name = "itm_pak_qty")
private Integer itemPackQuantity;
}
GroupingForm.java
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
#Entity
#Table(name = "GroupingForm")
public class GroupingForm implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
#GeneratedValue(generator = "uuid")
#Column(name = "grouping_form_id",unique = true, nullable = false)
private UUID groupingFormId;
#Column(name = "grouping_form_name")
private String groupingFormName;
#Column(name = "vid")
private String vid;
#Column(name = "vendor_name")
private String vendorName;
#Column(name = "hovbu")
private String hovbu;
#Column(name = "fid")
private String fid;
#Column(name = "factory_name")
private String factoryName;
#Column(name = "item_count")
private Integer itemCount;
#CreationTimestamp
#Column(name = "creation_date")
private Timestamp creationDate;
#Column(name = "created_by")
private String createdBy;
#UpdateTimestamp
#Column(name = "modified_date")
private Timestamp modifiedDate;
#Column(name = "modified_by")
private String modifiedBy;
#Column(name = "product_engineer")
private String productEngineer;
#Column(name = "status")
private String status;
#Column(name = "sourcing_type")
private String sourcingType;
#Column(name = "total_comments")
private Integer totalComments;
#Column(name = "factory_name_chinese")
private String factoryNameChinese;
#Column(name = "grouping_form_type")
private String groupingFormType;//to save as Product/transit/Product_transit
#Column(name = "ref_id")
private String refId;
#JsonBackReference
#OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL)
private List<ProductItemsMapping> productItems = new ArrayList<>();
#JsonBackReference
#OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL)
private List<TransitItemsMapping> transitItems = new ArrayList<>();
#Column(name = "pdf_status")
private String pdfStatus;
public GroupingForm(UUID groupingFormId,String groupingFormName, String vid, String vendorName, String hovbu,
String fid, String factoryName, String status, String sourcingType, Integer totalComments,
Date creationDate, String createdBy, Date modifiedDate, String modifiedBy, String productEngineer,
Integer itemCount, String groupingFormType, String refId, String factoryNameChinese) {
this.groupingFormId = groupingFormId;
this.groupingFormName = groupingFormName;
this.vid = vid;
this.vendorName = vendorName;
this.hovbu = hovbu;
this.fid = fid;
this.factoryName = factoryName;
this.status = status;
this.sourcingType = sourcingType;
this.totalComments = totalComments;
this.creationDate = creationDate!=null?new Timestamp(creationDate.getTime()):null;
this.createdBy = createdBy;
this.modifiedDate = modifiedDate!=null?new Timestamp(modifiedDate.getTime()):null;
this.modifiedBy = modifiedBy;
this.productEngineer = productEngineer;
this.itemCount = itemCount;
this.groupingFormType = groupingFormType;
this.refId = refId;
this.factoryNameChinese = factoryNameChinese;
}
}
Service: methods which already annotated with #Transactional
private void updateTransitItem(GroupingCardsDto groupingCardsDto, GroupingForm groupingForm) {
transitItemRepository.deleteByGroupingFormId(groupingCardsDto.getGroupingFormDto().getGroupingFormId());
groupingFormService.saveTransitItems(groupingCardsDto.getGroupingFormDto(), groupingForm);
}
when I am running eclipse in debug mode then my breakpoint is stuck in delete method. I am using
PostgreSQL 9.6.24 on x86_64-pc-linux-gnu, compiled by Debian clang version 12.0.1, 64-bit
version, and for pool connection Hikari-CP-3.2.0.
And If I let my debug running after long time (~45min) I am getting below error.
marked as broken because of SQLSTATE(08006), ErrorCode(0)\norg.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
Thanks in advance.
There are two possible reasons for this.
Either your delete statement actually takes a really long time, or it is stuck on a lock.
45 min, is certainly a lot for simple delete and could only be expected when you are working on huge amounts of data, like many millions of rows. Use the explain plan to validate that the expected indexes are used.
I consider locks the more likely reason for the problem. You'll need to check what locks are present and where they are coming from. This wiki page about lock monitoring in PostgreSQL seems to be a good starting point.
I am working on a Spring Boot project using Spring Data JPA trying to adopt the "query by method name" style in order to define my queries into repositories.
I am finding some difficulties trying to implement a select query retrieving the list of objects based on two different "where condition". I will try to explain what I have to do.
First of all this is my main entity class named Wallet:
#Entity
#Table(name = "wallet")
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Wallet implements Serializable {
private static final long serialVersionUID = 6956974379644960088L;
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name = "address")
private String address;
#Column(name = "notes")
private String notes;
#ManyToOne
#EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
#JoinColumn(name = "fk_user_id", referencedColumnName = "id")
#JsonBackReference(value = "user-wallets")
private User user;
#ManyToOne
#EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
#JoinColumn(name = "fk_coin_id", referencedColumnName = "id")
private Coin coin;
#ManyToOne
#JoinColumn(name = "type", referencedColumnName = "id")
private WalletType walletType;
public Wallet(String address, String notes, User user, Coin coin, WalletType walletType) {
super();
this.address = address;
this.notes = notes;
this.user = user;
this.coin = coin;
this.walletType = walletType;
}
}
As you can see a wallet is directly binded to a specific User object and to a specific Coin object.
For completeness this is the code of my User entity class:
#Entity
#Table(name = "portal_user")
#Getter
#Setter
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class User implements Serializable {
private static final long serialVersionUID = 5062673109048808267L;
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name = "first_name")
#NotNull(message = "{NotNull.User.firstName.Validation}")
private String firstName;
#Column(name = "middle_name")
private String middleName;
#Column(name = "surname")
#NotNull(message = "{NotNull.User.surname.Validation}")
private String surname;
#Column(name = "sex")
#NotNull(message = "{NotNull.User.sex.Validation}")
private char sex;
#Column(name = "birthdate")
#NotNull(message = "{NotNull.User.birthdate.Validation}")
private Date birthdate;
#Column(name = "tax_code")
#NotNull(message = "{NotNull.User.taxCode.Validation}")
private String taxCode;
#Column(name = "e_mail")
#NotNull(message = "{NotNull.User.email.Validation}")
private String email;
#Column(name = "pswd")
#NotNull(message = "{NotNull.User.pswd.Validation}")
private String pswd;
#Column(name = "contact_number")
#NotNull(message = "{NotNull.User.contactNumber.Validation}")
private String contactNumber;
#Temporal(TemporalType.DATE)
#Column(name = "created_at")
private Date createdAt;
#Column(name = "is_active")
private boolean is_active;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
#JsonManagedReference(value = "address")
private Set<Address> addressesList = new HashSet<>();
#ManyToMany(cascade = { CascadeType.MERGE })
#JoinTable(
name = "portal_user_user_type",
joinColumns = { #JoinColumn(name = "portal_user_id_fk") },
inverseJoinColumns = { #JoinColumn(name = "user_type_id_fk") }
)
private Set<UserType> userTypes;
#ManyToOne(fetch = FetchType.LAZY)
#JsonProperty("subagent")
private User parent;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
#JsonManagedReference(value = "user-wallets")
private Set<Wallet> wallets = new HashSet<>();
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String firstName, String middleName, String surname, char sex, Date birthdate, String taxCode,
String email, String pswd, String contactNumber, Date createdAt, boolean is_active) {
super();
this.firstName = firstName;
this.middleName = middleName;
this.surname = surname;
this.sex = sex;
this.birthdate = birthdate;
this.taxCode = taxCode;
this.email = email;
this.pswd = pswd;
this.contactNumber = contactNumber;
this.createdAt = createdAt;
this.is_active = is_active;
}
}
and this is the code of my Coin entity class:
#Entity
#Table(name = "coin")
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Coin implements Serializable {
private static final long serialVersionUID = 6956974379644960088L;
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name = "name")
#NotNull(message = "{NotNull.Coin.name.Validation}")
private String name;
#Column(name = "description")
private String description;
#Column(name = "code", unique = true)
#NotNull(message = "{NotNull.Coin.code.Validation}")
private String code;
#Type(type="org.hibernate.type.BinaryType")
#Column(name = "logo")
private byte[] logo;
}
Then I have this WalletRepository interface:
public interface WalletRepository extends JpaRepository<Wallet, Integer> {
}
Here I need to define a query by name method that retrieve a specific wallet of a specific User (I think that I can query by the id field of the User) and based and related to a specific Coin (I think that I can query by the id fied of the Coin).
How can I implement a behavior like this?
The following should work:
public interface WalletRepository extends JpaRepository<Wallet, Integer> {
List<Wallet> findByUserIdAndCoinId();
}
You can read more about this at:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords
User table not saving PasswordInfo object automatically
Here are my entities
User entity
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#Column(name = "username")
private String userName;
#Column(name = "password")
private String password;
#Column(name = "emp_id")
private int empId;
#Column(name = "designation")
private String designation;
#Column(name = "status")
private String status;
#Column(name = "email_id")
private String emailId;
#Column(name = "account_status")
private String accountStatus;
#Column(name = "validity_date")
private Date validityDate;
#Column(name = "deactivation_date")
private Date deactivationDate;
#Column(name = "deactivated_by")
private String deactivatedBy;
#Column(name = "deactivation_remarks")
private String deactivationRemarks;
#OneToMany(fetch = FetchType.LAZY,
mappedBy = "user",
cascade = {CascadeType.PERSIST,CascadeType.MERGE,
CascadeType.DETACH,CascadeType.REFRESH})
private List<LoginDetails> loginDetails;
// add convenience methods for bi-directional relationship for LoginDetails
public void add(LoginDetails tempLoginDetails) {
if(loginDetails == null) {
loginDetails = new ArrayList<LoginDetails>();
}
loginDetails.add(tempLoginDetails);
tempLoginDetails.setUser(this);
}
#OneToOne(mappedBy = "user", fetch = FetchType.LAZY,
cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH})
private PasswordInfo passwordInfo;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "users_roles",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Collection<Role> roles;
#ManyToOne(fetch = FetchType.LAZY,cascade= {CascadeType.PERSIST,CascadeType.MERGE,
CascadeType.DETACH,CascadeType.REFRESH})
#JoinColumn(name="department_id")
private Department department;
#ManyToOne(fetch = FetchType.LAZY,cascade= {CascadeType.PERSIST,CascadeType.MERGE,
CascadeType.DETACH,CascadeType.REFRESH})
#JoinColumn(name="branch_id")
private Branch branch;
/*
* TIMESTAMPS START
* */
#Temporal( TemporalType.TIMESTAMP )
#CreationTimestamp
#Column(name = "creation_date")
private Date creationDate;
#UpdateTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updation_date")
private Date updationDate;
#ManyToOne(fetch = FetchType.LAZY,cascade={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH})
#JoinColumn(name="created_by")
private User createdBy;
#OneToMany(mappedBy="createdBy")
private Set<User> createdBySet = new HashSet<User>();
#ManyToOne(fetch = FetchType.LAZY,cascade={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH})
#JoinColumn(name="updated_by")
private User updatedBy;
#OneToMany(mappedBy="updatedBy")
private Set<User> updatedBySet = new HashSet<User>();
#PrePersist
protected void onCreate() {
creationDate = new Date();
}
#PreUpdate
protected void onUpdate() {
updationDate = new Date();
}
/*
* TIMESTAMPS END
* */
public User() {
}
// getter and setters and imports are written in real code, i have omitted them here
}
PasswordInfo entity
#Entity
#Table(name = "password_info")
public class PasswordInfo {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "last_password_1")
private String lastPassword1;
#Column(name = "last_password_2")
private String lastPassword2;
#Column(name = "last_password_3")
private String lastPassword3;
#Column(name = "last_password_4")
private String lastPassword4;
#Column(name = "last_password_5")
private String lastPassword5;
#Column(name = "forced_password_flag")
private String forcedPasswordFlag;
#Column(name = "pass_count")
private int passCount;
#Column(name = "password_date")
private Date passwordDate;
#OneToOne(fetch = FetchType.LAZY,cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH})
#JoinColumn(name="user_id")
private User user;
#Temporal( TemporalType.TIMESTAMP )
#CreationTimestamp
#Column(name = "creation_date")
private Date creationDate;
#PrePersist
protected void onCreate() {
creationDate = new Date();
}
public PasswordInfo() {
}
// getter and setters and imports are written in real code, i have omitted them here
}
This is my save method in service class
#Override
#Transactional
public String save(ReportUser reportUser) {
User user = new User();
// assign user details to the user object
user.setUserName(reportUser.getUserName());
user.setPassword(passwordEncoder.encode(reportUser.getPassword()));
user.setName(reportUser.getName());
user.setEmpId(reportUser.getEmpId());
user.setDesignation(reportUser.getDesignation());
user.setEmailId(reportUser.getEmailId());
user.setStatus(reportUser.getStatus());
user.setEmailId(reportUser.getEmailId());
user.setAccountStatus(reportUser.getAccountStatus());
user.setValidityDate(reportUser.getValidityDate());
String loggedInUser = jwtUtil.getUsername();
logger.info(">>>>> Logged In USER " + loggedInUser);
Department theDepartment = departmentDao.getDepartment(reportUser.getDepartmentId());
Branch theBranch = branchDao.getBranch(reportUser.getBranchId());
User createdByUser = userDao.findByUserName(loggedInUser);
user.setBranch(theBranch);
user.setDepartment(theDepartment);
user.setCreatedBy(createdByUser);
String[] roleArr = reportUser.getFormRole().split(",");
List<Role> roleList = new ArrayList<Role>();
for(String r: roleArr) {
roleList.add(roleDao.findRoleByName(r));
}
Collection<Role> roles = roleList;
user.setRoles(roles);
ParameterMst pmst = otherDao.getParameterValueById(1L);
int passwordExpirationDays = Integer.valueOf(pmst.getValue());
PasswordInfo pInfo = new PasswordInfo();
// Add passwordExpirationDays to current date
Date passwordExpirationDate = DateUtils.asDate(LocalDate.now().plusDays(passwordExpirationDays));
logger.info(">>>>> Password Expiration Date " + passwordExpirationDate);
pInfo.setPasswordDate(passwordExpirationDate);
pInfo.setPassCount(12);
pInfo.setUser(user);
user.setPasswordInfo(pInfo);
// save user in the database
userDao.save(user);
return user.getUserName();
}
This is save in DAO Implementation
#Override
public void save(User user) {
// get current hibernate session
Session currentSession = sessionFactory.getCurrentSession();
currentSession.saveOrUpdate(user);
}
Due to bi-directional relationship set in User, i should be able to update both in one go, rather than doing separately.
Why this isn't working?
Please Help!
Don't use mappedBy and #JoinColumn together as they serve slightly different purposes.
See the uses of both and use either one of them.
Try removing #JoinColumn annotation from PasswordInfo entity.
Try to annotate like this
In class PasswordInfo :
#OneToOne(mappedBy = "passwordInfo")
private User user;
In class User
#OneToOne()
private PasswordInfo passwordInfo;
mappedBy say that User table is the owner of the relationship using its propertie passwordInfo.
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.
I have following entity classes:
#MappedSuperclass
public class AbstractEntity implements Serializable, Comparable<AbstractEntity> {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
protected Integer id;
#Override
public int compareTo(AbstractEntity o) {
return this.toString().compareTo(o.toString());
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
#Entity
#Table(name = "ticket")
#NamedQueries({
#NamedQuery(name = "Ticket.findAll", query = "SELECT t FROM Ticket t")})
public class Ticket extends AbstractEntity {
#Column(name = "title")
private String title;
#Column(name = "description")
private String description;
#Enumerated(EnumType.STRING)
#Column(name = "status")
private TicketStatus status;
#Enumerated(EnumType.STRING)
#Column(name = "priority")
private TicketPriority priority;
#Column(name = "categories")
private String categories;
#Column(name = "views")
private Integer views;
#Column(name = "date_time_created")
#Temporal(TemporalType.TIMESTAMP)
private Date dateTimeCreated;
#Column(name = "date_time_modified")
#Temporal(TemporalType.TIMESTAMP)
private Date dateTimeModified;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "ticketId")
private List<TicketFollower> ticketFollowerList;
#JoinColumn(name = "project_id", referencedColumnName = "id")
#ManyToOne(optional = false)
private Project projectId;
#JoinColumn(name = "ticket_attachment_id", referencedColumnName = "id")
#ManyToOne
private TicketAttachment ticketAttachmentId;
#JoinColumn(name = "user_id", referencedColumnName = "id")
#ManyToOne(optional = false)
private User userId;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "ticketId")
private List<TicketComment> ticketCommentList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "ticketId")
private List<TicketAttachment> ticketAttachmentList;
#Inject
public Ticket() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
...
#Override
public String toString() {
return getTitle();
}
}
#Entity
#Table(name = "user")
#NamedQueries({
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")})
public class User extends AbstractEntity {
#Enumerated(EnumType.STRING)
#Column(name = "role")
private Role role;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "email")
private String email;
#Column(name = "avatar_path")
private String avatarPath;
#Column(name = "date_time_registered")
#Temporal(TemporalType.TIMESTAMP)
private Date dateTimeRegistered;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
private List<TicketFollower> ticketFollowerList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
private List<Ticket> ticketList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
private List<TicketComment> ticketCommentList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
private List<ProjectFollower> projectFollowerList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
private List<TicketAttachment> ticketAttachmentList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
private List<Project> projectList;
#Inject
public User() {}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
I get this exception from creating a hibernate Criteria. In my TicketDao class I have a method which search ticket by username, and when I invoke code below
Criteria criteria = session.createCriteria(Ticket.class);
criteria.add(Restrictions.eq("userId.username", username));
it throws exception:
could not resolve property: userId.username of: com.entities.Ticket
However, when I write criteria like:
criteria.add(Restrictions.eq("userId.id", userId));
it does not show any exception and returns me result. Any idea why my syntax for criteria.add(Restrictions.eq("userId.username", username)); and other properties like firstname, last name is wrong ?
Criteria does not work like EL or Java methods or attributes, you cannot refer to inner objects with a dot ..
You have to create a restriction in Ticket, right? What does Ticket has? An User. Then... you have to create a new User, set the username to this User and then set the created User to Ticket's criteria:
Criteria criteria = session.createCriteria(Ticket.class);
User user = new User();
user.setUsername(username);
criteria.add(Restrictions.eq("user", user));