spring data not get id annotaion on method - spring-data

When my Entity id annotation on field, it's OK on spring data jpa.
public class User {
#Id
#Column(name="id")
Long rid;
#Column(name="name")
String name;
}
but not work on method...
public class User {
Long rid;
String name;
#Id
#Column(name="id")
public Long getId() {
return this.id;
}
#Column(name="name")
public Long getName() {
return this.name;
}
}
the error message is PersistentEntity does not have an identifier property!
why?
I need to set annotation on method, because I want to set association auto.
#OneToMany(mappedBy="user")
#Cascade(CascadeType.ALL)
public Set<Phone> getPhones() {
return smtpRecords;
}
public void setPhones(Set<Phone> phones) {
phones.forEach(e -> e.setUser(this));
this.phones= phones;
}
any solution? Thanks.

Related

Want to automatically insert current Date in the table When a post Request is made

I have a User Entity and an Order Entity.
One of the field in order entity is date.
Till now i have the user enter the date.
Now i want that at the time post request is made the date is automatically set to the current date and stored in the database.
Tried using #Prepersist annotation But since this is my first API that i am developing using springBoot , I don't really know how to use it.
User Entity
#Entity
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private BigInteger id;
#NotEmpty(message = "Name is compulsory")
#Pattern(regexp="^[A-Za-z]*[A-Za-z-'. ]*[A-Za-z]*$",message = "Name has invalid characters")
private String username;
//#NotEmpty(message = "Phone Number is compulsary")
#Range(min = 6400000000L ,max=9999999999L)
private Long phoneNumber;
#NotEmpty(message = "Address is compulsary")
private String address;
public User(){}
public User(BigInteger id, String username, Long phoneNumber, String address) {
super();
this.id = id;
this.username = username;
this.phoneNumber = phoneNumber;
this.address = address;
}
public BigInteger getId() {
return id;
}
public void setId(BigInteger id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Long getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(Long phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Order Entity
#Entity
public class Orders {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private BigInteger id;
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
private Date date;
#ManyToOne
private User user;
public Orders(){}
public Orders(BigInteger id, Date date,BigInteger userId) {
super();
this.id = id;
this.date = date;
this.user=new User(userId," ",0000000000L," ");
}
public BigInteger getId() {
return id;
}
public void setId(BigInteger id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Order Controller
#RestController
public class OrdersController {
#Autowired
private OrdersService ordersService;
#ApiOperation(value="Show all orders")
#RequestMapping("/orders")
public Iterable<Orders> getAllOrders()
{
return ordersService.getAllOrders();
}
#ApiOperation(value="Show a particular Order")
#RequestMapping("/orders/{orderId}")
public Orders getOrderById(#PathVariable BigInteger orderId)
{
return ordersService.getOrderById(orderId);
}
#ApiOperation(value="Show all orders of a particular User")
#RequestMapping("/users/{id}/orders")
public List<Orders> getOrders(#PathVariable BigInteger id) {
return ordersService.getOrders(id);
}
#ApiOperation(value="Show an order for a User")
#RequestMapping("/users/{userId}/orders/{id}")
public Orders getOrder(#PathVariable BigInteger id){
return ordersService.getOrder(id);
}
#ApiOperation(value="Adds a new Order")
#RequestMapping(method = RequestMethod.POST,value = "/users/{userId}/orders")
public Orders addOrder(#PathVariable BigInteger userId,#RequestBody Orders orders) {
orders.setUser(new User(userId," ",0000000000L," "));
return ordersService.addOrder(orders);
}
#ApiOperation(value="Alter an Order")
#RequestMapping(method = RequestMethod.PUT, value="/users/{userId}/orders/{id}")
public Orders updateOrder(#RequestBody Orders order,#PathVariable BigInteger id,#PathVariable BigInteger userId)throws Exception {
order.setUser(new User(userId," ",0000000000L," "));
return ordersService.updateOrder(order, id);
}
#ApiOperation(value="Delete an Order")
#RequestMapping(method = RequestMethod.DELETE, value="/orders/{id}")
public void deleteOrder(#PathVariable BigInteger id){
ordersService.deleteOrder(id);
}
}
#PrePersist is a JPA annotation and therefore should work in all compatible persistence frameworks. It indicates a method that should be invoked on particular entity lifecycle event. (Other events are well documented in the Hibernate user guide here).
Add this to your entity:
#Temporal(TemporalType.TIMESTAMP)
#Column(nullable = false)
private Date timestamp;
#PrePersist
private void onCreate() {
timestamp = new Date();
}
As for assigning/creating the entity in the controller, it is a good practice to use DTO (data transfer objects) in your controller (#RequestBody OrderDto orderDto) and then use some method to populate a new entity instance with those values. Most common options are
modelmapper
manually
...
Order o = new Order();
o.user = userDao.findById(orderDto.getUserId());
...
// persist o

There is no ID defined for this entity hierarchy

I am stuck with this error message, that appears every time I want to add a ManytoOne relationship with another entity class.
The class must use a consistent access type (either field or property). There is no ID defined for this entity hierarchy
This is my entity Transaction
#Entity
#Table(name = "CustomerTransaction")
public class CustomerTransaction implements Serializable {//this is the line with the error message
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne //This generates the problem
#JoinColumns({
#JoinColumn(name = "CUS_ID", referencedColumnName = "IDCUSTOMER") })
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private long transactionID;
#Temporal(TemporalType.TIMESTAMP)
private Date buyDate;
public Date getBuyDate() {
return buyDate;
}
public void setBuyDate(Date buyDate) {
this.buyDate = buyDate;
}
public long getTransactionID() {
return transactionID;
}
public void setTransactionID(long transactionID) {
this.transactionID = transactionID;
}
public String getCarYear() {
return carYear;
}
public void setCarYear(String carYear) {
this.carYear = carYear;
}
public Date getTransactionDate() {
return transactionDate;
}
public void setTransactionDate(Date transactionDate) {
this.transactionDate = transactionDate;
}
private String carYear;
#Temporal(TemporalType.TIMESTAMP)
private Date transactionDate;
JPA annotation should all be placed either on fields or on accessor methods. You've placed the #Id and #GeneratedValue annotation on a field (private Long id), but #ManyToOne and #JoinColumns on a getter (public Long getId()). Move the latter on a field as well.
i had similar error but in the end, i realized #Id was referencing this package org.springframework.data.annotation.Id instead of javax.persistence.Id. i was using #MappedSuperClass approach so as soon as i corrected this, everything worked fine
You need to import #Id from "import javax.persistence.Id;"

org.hibernate.TransientObjectException: object references an unsaved transient instance

I am trying to establish unidirectional relationship between two entities called Person and Address,while saving Person(containing collection of Address) getting org.hibernate.TransientObjectException: object references an unsaved transient instance.
When I change cascadeType=all,child objects are getting propagated.But the problem here is with cascadeType=all Hibernate also tries to delete child entities on Deleting Owning entity.I don't want that to happen because in ManyToMany relationship child entity might be being referenced by some other entity.Ideally cascadeType=persist should do the job but unfortunately that give me mentioned exception.
Can somebody help me out how can I save the child objects (Address) with cascadeType=persist.I just wonder why cascadeType=persist is not doing the task of persisting.
public class Person {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String name;
#LazyCollection(LazyCollectionOption.FALSE)
#ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE})
private Collection<Address> address=new HashSet<Address>();
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 Collection<Address> getAddress() {
return address;
}
public void setAddress(Collection<Address> address) {
this.address = address;
}
}
#Entity(name="Address")
public class Address {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Long id;
#Column(name="country")
private String country;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
In case of many- many relationship you always have to make use of JOIN Table(which is a third table).In that case you dont have a problem of Child entities getting deleted on deleting the Owning entity even if you use CASCADE-ALL.
Please see following post below:
Modeling many-to-many Relationship in JPA/Hibernate

JPA find from composite Key

I have a class like this...
#Entity
public class User{
private String userId;
#Id
public String getUserId(){
return userId;
}
public void setUserId(String userId){
this.userId = userId;
}
}
#Embeddible
public class RegPk{
private String serial;
private String userId;
....
}
#Entity
#IdClass(RegPk.class)
public class Registration {
private String userId, serial;
private User user
#Id
#Column(name="SRL_C")
public String getSerial() {return serial;}
public void setSerial(String serial) {this.serial = serial;}
#ManyToOne(cascade={CascadeType.REFRESH})
#JoinColumn(name="USERID", referencedColumnName="USERID", nullable = false)
public User getUser() {return user;}
public void setUser(User user) {this.user = user;}
#Id
#Column(name="USERID", nullable = false)
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
RegPk pk = new RegPk();
pk.setSerial(dr.getSerial());
pk.setUserId(dr.getUserId());
Registration userOld = em.find(Registration.class, pk);
But when I try to run it I get null back. I swear I thought I had it working so...
1.) is this kind of thing even possible?
2.) what am I doing wrong?
Yes, it's possible, provided you use the MapsId annotation. Otherwise, you have two different fields mapped to the same column, which is invalid.
The javadoc provides an example which almost matches exactly with your situation.

Copy Entity ID at persist time

I want to copy the entity's UUID, generated at run time to another field.
The entity id is generated via the code described bellow:
package eclipselink.example;
public class UUIDSequence extends Sequence implements SessionCustomizer {
public UUIDSequence() {
super();
}
public UUIDSequence(String name) {
super(name);
}
#Override
public Object getGeneratedValue(Accessor accessor,
AbstractSession writeSession, String seqName) {
return UUID.randomUUID().toString().toUpperCase();
}
...
public void customize(Session session) throws Exception {
UUIDSequence sequence = new UUIDSequence("system-uuid");
session.getLogin().addSequence(sequence);
}
}
Persitence.xml:
property name="eclipselink.session.customizer" value="eclipselink.example.UUIDSequence"
The entity:
public abstract class MyEntity{
private String id;
private String idCopy;
#Id
#Basic(optional = false)
#GeneratedValue(generator="system-uuid")
#XmlElement(name = "ID")
public String getId() {
return id;
}
}
How can I instruct JPA (Eclipse-link) to copy the UUID generated at runtime to idCopy field as well?
I'm not 100% sure this will work (I don't know if EclipseLink calls the setter or assigns the field directly), but give this a try:
public abstract class MyEntity{
private String id;
private String idCopy;
#Id
#Basic(optional = false)
#GeneratedValue(generator="system-uuid")
#XmlElement(name = "ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
this.idCopy = id;
// or
// this.setIdCopy(id);
}
}