Save object with Hibernate annotations? - java

I just wanna ask know how its possible to create object after creating your database with Hibernate annotations?
When i run the code below, it creates the database with the objects, but when i run the second time it just creates exactly the same, and none new objects are added? How come? How do i create objects using annotations with the method .save, after creating the database with annotations? Or is it not possible to do so with annotations?
Thanks in advance.
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
Adress adress = new Adress("Streetname", "postcode");
Person person1 = new Person("Peter Hanks", adress);
Person person2 = new Person("Sophie Hanks", adress);
session.save(person1);
session.save(person2);
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
Heres the code person.class
#Entity
#Table(name="person")
public class Person implements Serializable {
private long id;
private String navn;
private Adresse adresse;
public Person() {
}
public Person(String navn, Adresse adresse) {
this.navn = navn;
this.adresse = adresse;
}
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name= "adresse_id", nullable = false)
public Adresse getAdresse() {
return adresse;
}
public void setAdresse(Adresse adresse) {
this.adresse = adresse;
}
#Id
#GeneratedValue
#Column(name= "id")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#Column(name = "navn", nullable= false, length= 100)
public String getNavn() {
return navn;
}
public void setNavn(String navn) {
this.navn = navn;
}
#Override
public int hashCode() {
int hash = 3;
hash = 29 * hash + (this.navn != null ? this.navn.hashCode() : 0);
hash = 29 * hash + (this.adresse != null ? this.adresse.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
if ((this.navn == null) ? (other.navn != null) : !this.navn.equals(other.navn)) {
return false;
}
if (this.adresse != other.adresse && (this.adresse == null || !this.adresse.equals(other.adresse))) {
return false;
}
return true;
}

You might need to show us how you've written and annotated your Person and Adress (sic) objects.
If you've written "correct" equals() and hashcode() implementations (i.e. that don't look at the #Id of the object) then your save() calls will do nothing the second time around because the objects you've asked to save already exist in the database.

just changed the settings for hibernate.hbm2ddl.auto from create to create-update, and now theres no problem...

Related

Can't add an object to a Set

Hi I have a little problem in java, I do not have an error but I do not get what I want. Here I create 3 Pizza with and I want to put them in a set, the problem is that when I print my set I only have One Pizza which is the first one p1.
Here's the code :
Pizza p1 = new Pizza(cannibale, Taille.Large, TypePate.Classique);
Pizza p2 = new Pizza(forestiere, Taille.XL, TypePate.Fine);
Pizza p3 = new Pizza(hypnotika, Taille.Medium, TypePate.MozzaCrust);
Set<Pizza> pizzas = new HashSet<Pizza>();
Collections.addAll(pizzas, p1,p2,p3);
Pizza
#Entity
#Table(name = "pizza")
#SequenceGenerator(name = "seqPizza", sequenceName = "seq_pizza", initialValue = 1, allocationSize = 1)
public class Pizza {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqPizza")
#Column(name = "id")
private Long id;
#ManyToOne
#JoinColumn(name = "recette", foreignKey = #ForeignKey(name = "PIZZA_RECETTE_ID_FK"))
private Recette recette;
#ManyToOne
#JoinColumn(name = "numticket_id", foreignKey = #ForeignKey(name = "PIZZA_NUMTICKET_ID_FK"))
private Commande commandePizza;
#Column(name = "prix")
private double prix;
#Enumerated(EnumType.STRING)
#Column(name = "taille_pizza")
private Taille taille;
#Enumerated(EnumType.STRING)
#Column(name = "type_pate")
private TypePate pate;
public Pizza() {
}
public Pizza(Recette recette, Taille taille, TypePate pate) {
this.recette = recette;
this.taille = taille;
this.pate = pate;
if (taille == Taille.Medium) {
this.prix = recette.getPrixM();
} else if (taille == Taille.Large) {
this.prix = recette.getPrixL();
} else {
this.prix = recette.getPrixXL();
}
if (pate == TypePate.MozzaCrust) {
this.prix = this.prix + pate.getPrix();
} else if (pate == TypePate.Pan) {
this.prix = this.prix + pate.getPrix();
} else {
this.prix = this.prix + pate.getPrix();
}
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Commande getCommandePizza() {
return commandePizza;
}
public void setCommandePizza(Commande commandePizza) {
this.commandePizza = commandePizza;
}
public double getPrix() {
return prix;
}
public void setPrix(double prix) {
this.prix = prix;
}
public Recette getRecette() {
return recette;
}
public void setRecette(Recette recette) {
this.recette = recette;
}
public Taille getTaille() {
return taille;
}
public void setTaille(Taille taille) {
this.taille = taille;
}
public TypePate getPate() {
return pate;
}
public void setPate(TypePate pate) {
this.pate = pate;
}
#Override
public int hashCode() {
return Objects.hash(id);
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pizza other = (Pizza) obj;
return Objects.equals(id, other.id);
}
You can find all the code here : https://github.com/HamzaMerini/help/tree/main/pizzayolo
Thank you !!
Even if your class is annotated with Entity, it won't work similar way when you are instantiating object manually; i.e. while persisting Pizza into db, you might have seen new id got assigned to every insert / save call because of #SequenceGenerator.
But when you do manual instantiation of Pizza & trying to insert it to HashSet, it will check if there is any pre-existing Pizza available based on hashCode. Manual instantiation will assign default value 0 to id & hence only first insertion to HashSet succeed.
Change hashCode so that it will generate some unique value & that way Collections.addAll will work.
HashSets use the hashCode to compute identity. Your pizzas seem to have the same ID. Hence you don't provide one in the constructor nor sets one, it stay null, for all three pizzas. You could persist all those and have the database provide ids, or set them yourself.
When you use at least Java 9, you could use the utility method:
Set<Pizza> pizzas = java.util.Set.of(p1, p2, p3);
For older versions you can use:
Set<Pizza> pizzas = new HashSet<>;
pizzas.add(p1);
pizzas.add(p2);
pizzas.add(p3);

detached entity passed to persist for batch insert in JPA

For the following batch insert method, i get this exception "detached entity passed to persist". Could you take a look at this method and give me some hints?
Thank you so much.
if needed, I will provided the entities here, for the moment I provide Keyword entity :
public class Keyword implements Serializable {
private static final long serialVersionUID = -1429681347817644570L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="key_id")
private long keyId;
#Column(name="key_name")
private String keyName;
#ManyToOne
#JoinColumn(name="tweet_id")
private Tweet tweet;
public long getKeyId() {
return keyId;
}
public void setKeyId(long keyId) {
this.keyId = keyId;
}
public String getKeyName() {
return keyName;
}
public void setKeyName(String keyName) {
this.keyName = keyName;
}
public Tweet getTweet() {
return tweet;
}
public void setTweet(Tweet tweet) {
this.tweet = tweet;
}
}
Here Tweet Entity :
#Entity
#Table(name="tweets")
public class Tweet implements Serializable{
#Id
#Column(name="tweet_id")
private long tweetId;
#Column(name="tweet_text")
private String tweetText;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "created_at")
private Date createdAt;
#Column(name="lang_code")
private String languageCode;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
#OneToMany(mappedBy="tweet")
//#JoinColumn(name="hashtag_id")
private List<Hashtag> hashtags;
#OneToMany(mappedBy="tweet")
//#JoinColumn(name="url_id")
private List<Url> urls;
public List<Keyword> getKeywords() {
return keywords;
}
public void setKeywords(List<Keyword> keywords) {
this.keywords = keywords;
}
#OneToMany(mappedBy="tweet")
//#JoinColumn(name="url_id")
private List<Keyword> keywords;
public long getTweetId() {
return tweetId;
}
public void setTweetId(long tweetId) {
this.tweetId = tweetId;
}
public String getTweetText() {
return tweetText;
}
public void setTweetText(String tweetText) {
this.tweetText = tweetText;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public String getLanguageCode() {
return languageCode;
}
public void setLanguageCode(String languageCode) {
this.languageCode = languageCode;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Hashtag> getHashtags() {
return hashtags;
}
public void setHashtags(List<Hashtag> hashtags) {
this.hashtags = hashtags;
}
public List<Url> getUrls() {
return urls;
}
public void setUrls(List<Url> urls) {
this.urls = urls;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (tweetId ^ (tweetId >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Tweet other = (Tweet) obj;
if (tweetId != other.tweetId)
return false;
return true;
}
And here Url entity :
#Entity
#Table(name="tweet_url")
public class Url implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="url_id")
private int urlId;
#Column(name="url")
private String url;
#ManyToOne
#JoinColumn(name="tweet_id",referencedColumnName="tweet_id")
private Tweet tweet;
public int getUrlId() {
return urlId;
}
public void setUrlId(int urlId) {
this.urlId = urlId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Tweet getTweet() {
return tweet;
}
public void setTweet(Tweet tweet) {
this.tweet = tweet;
}
And here is hashtag entity :
#Entity
#Table(name="tweet_hashtag")
public class Hashtag implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="hashtag_id")
private int hashtagId;
#Column(name="hashtag")
private String hashtag;
#ManyToOne
#JoinColumn(name="tweet_id",referencedColumnName="tweet_id")
private Tweet tweet;
public int getHashtagId() {
return hashtagId;
}
public void setHashtagId(int hashtagId) {
this.hashtagId = hashtagId;
}
public String getHashtag() {
return hashtag;
}
public void setHashtag(String hashtag) {
this.hashtag = hashtag;
}
public Tweet getTweet() {
return tweet;
}
public void setTweet(Tweet tweet) {
this.tweet = tweet;
}
And the method :
public void batchInsert(List<Keyword> results) throws HibernateException {
// chekeywordck if key exists
// try {
em=RunQuery.emf.createEntityManager();
em.getTransaction().begin();
for(Keyword result:results)
{
try{
em.persist(result.getTweet().getUser());
}
catch(ConstraintViolationException ce)
{
System.out.print("duplicated insert catched");
}
try{
em.persist(result.getTweet());
}
catch(ConstraintViolationException ce)
{
System.out.print("duplicated insert catched");
}
if(result.getTweet().getHashtags()!=null)
for(Hashtag hashtag:result.getTweet().getHashtags())
em.persist(hashtag);
if(result.getTweet().getUrls()!=null)
for(Url url:result.getTweet().getUrls())
em.persist(url);
em.persist(result);
em.flush();
em.clear();
//when I put these two line out of this loop, it still is the same.
}
em.getTransaction().commit();
// }
}
And here is the exception :
Exception in thread "Thread-3" javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: model.twitter.entities.Url
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1187)
at model.service.QueryResultService.batchInsert(QueryResultService.java:74)
at controller.ResultsController.save(ResultsController.java:125)
at controller.ResultsController.parse(ResultsController.java:89)
at main.TwitterStreamConsumer.run(TwitterStreamConsumer.java:41)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: model.twitter.entities.Url
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
... 5 more
To answer your question: your model defines a one-to-many relationship between Tweet and URL without any cascading. When you are passing a Tweet instance for persisting, the URL objects have not yet been saved and your model does not mandate Tweet to cascade the persist operation to the URL instances. Therefore it can not create the relationship with them.
Cascading tells the hibernate, how to execute DB operations on related entities.
You can instruct it to pass/cascade the persist operation to the related entity, to cascade all operations or an array of operations.
That being said, your problem(1 of them) could be fixed if you modify the relationship with cascading info:
#OneToMany(mappedBy="tweet", cascade={CascadeType.PERSIST})
private List<Url> urls;
But your sample indicates other possible issues and I would encourage you to spent some more time reading Hibernate ORM documentation and practicing on sample model with less relationships.
One of the obvious issues seems to be the lack of understanding of relationship owner concept.
For example, in your Tweet-to-Url relationship, URL is the relationship owner(responsible for managing the relationship, e.g. managing the link via foreign key)
Please consult hibernate docs or one of hundreds of similar questions here on SO for more info.
Depending on how you fill the data, it is possible that you will run into constraint issues, or your entities will not be linked together, because you are not saving the owning side.
Also using try/catch for constraint violations is a very bad way of detecting duplicated entries. ConstraintViolationException can be have many causes and the reason you are getting them is related to the above mentioned relationship mapping issues.
ORM is complex subject and it is really beneficial to start with smaller examples, trying to understand the framework mechanics before moving to the more challenging models. Good Luck
For all the persist calls try using this instead:
if(result.getTweet().getUser().getId() == null) {
em.persist(result.getTweet().getUser());
} else {
result.getTweet().setUser(em.merge(result.getTweet().getUser()));
}
if(result.getTweet().getId() == null) {
em.persist(result.getTweet());
} else {
result.setTweet(em.merge(result.getTweet()));
}
if(result.getId() == null) {
em.persist(result);
} else {
result = em.merge(result);
}

Column does not exist - Hibernate ManyToMany association class

I'm facing the following problem. Imagine this data model:
As you can see project_function entity is association many to many entity.
Here are my entity classes.
PeronalCard:
#Entity
#Table(name = "personal_card")
#XmlRootElement
public class PersonalCard implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id_person")
private Integer idPerson;
/* SOME OTHER ATTRIBUTES */
#OneToMany(cascade = CascadeType.ALL, mappedBy = "projectFunctionPK.personalCard")
private Set<ProjectFunction> projectFunctionSet;
public PersonalCard() {
}
public Integer getIdPerson() {
return idPerson;
}
public void setIdPerson(Integer idPerson) {
this.idPerson = idPerson;
}
#XmlTransient
public Set<ProjectFunction> getProjectFunctionSet() {
return projectFunctionSet;
}
public void setProjectFunctionSet(Set<ProjectFunction> projectFunctionSet) {
this.projectFunctionSet = projectFunctionSet;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idPerson != null ? idPerson.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof PersonalCard)) {
return false;
}
PersonalCard other = (PersonalCard) object;
if ((this.idPerson == null && other.idPerson != null) || (this.idPerson != null && !this.idPerson.equals(other.idPerson))) {
return false;
}
return true;
}
}
Project:
#Entity
#Table(name = "project")
#XmlRootElement
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id_project")
private Integer idProject;
/* OTHER ATTRIBUTES*/
#OneToMany(cascade = CascadeType.ALL, mappedBy = "projectFunctionPK.project")
private Set<ProjectFunction> projectFunctionSet;
public Project() {
}
public Integer getIdProject() {
return idProject;
}
public void setIdProject(Integer idProject) {
this.idProject = idProject;
}
#XmlTransient
public Set<ProjectFunction> getProjectFunctionSet() {
return projectFunctionSet;
}
public void setProjectFunctionSet(Set<ProjectFunction> projectFunctionSet) {
this.projectFunctionSet = projectFunctionSet;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idProject != null ? idProject.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Project)) {
return false;
}
Project other = (Project) object;
if ((this.idProject == null && other.idProject != null) || (this.idProject != null && !this.idProject.equals(other.idProject))) {
return false;
}
return true;
}
}
ProjectFunction:
#Entity
#Table(name = "project_function")
#XmlRootElement
#AssociationOverrides({
#AssociationOverride(name = "projectFunctionPK.project",
joinColumns = #JoinColumn(name = "id_project", referencedColumnName = "id_project")),
#AssociationOverride(name = "projectFunctionPK.personalCard",
joinColumns = #JoinColumn(name = "id_person", referencedColumnName = "id_person")) })
public class ProjectFunction implements Serializable {
private static final long serialVersionUID = 1L;
protected ProjectFunctionPK projectFunctionPK;
private Date fromd;
private Date tod;
public ProjectFunction() {
this.projectFunctionPK = new ProjectFunctionPK();
}
#EmbeddedId
public ProjectFunctionPK getProjectFunctionPK() {
return projectFunctionPK;
}
public void setProjectFunctionPK(ProjectFunctionPK projectFunctionPK) {
this.projectFunctionPK = projectFunctionPK;
}
#Column(name = "fromd")
#Temporal(TemporalType.DATE)
public Date getFromd() {
return fromd;
}
public void setFromd(Date fromd) {
this.fromd = fromd;
}
#Column(name = "tod")
#Temporal(TemporalType.DATE)
public Date getTod() {
return tod;
}
public void setTod(Date tod) {
this.tod = tod;
}
#Transient
public Project getProject() {
return projectFunctionPK.getProject();
}
public void setProject(Project project) {
this.projectFunctionPK.setProject(project);
}
#Transient
public PersonalCard getPersonalCard() {
return this.projectFunctionPK.getPersonalCard();
}
public void setPersonalCard(PersonalCard personalCard) {
//this.personalCard = personalCard;
this.projectFunctionPK.setPersonalCard(personalCard);
}
#Override
public int hashCode() {
int hash = 0;
hash += (projectFunctionPK != null ? projectFunctionPK.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof ProjectFunction)) {
return false;
}
ProjectFunction other = (ProjectFunction) object;
if ((this.projectFunctionPK == null && other.projectFunctionPK != null) || (this.projectFunctionPK != null && !this.projectFunctionPK.equals(other.projectFunctionPK))) {
return false;
}
return true;
}
}
And finally my embedded Primary Key ProjectFunctionPK:
#Embeddable
public class ProjectFunctionPK implements Serializable {
#ManyToOne
private Project project;
#ManyToOne
private PersonalCard personalCard;
public ProjectFunctionPK() {
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public PersonalCard getPersonalCard() {
return personalCard;
}
public void setPersonalCard(PersonalCard personalCard) {
this.personalCard = personalCard;
}
#Override
public int hashCode() {
int hash = 3;
hash = 41 * hash + Objects.hashCode(this.project);
hash = 41 * hash + Objects.hashCode(this.personalCard);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ProjectFunctionPK other = (ProjectFunctionPK) obj;
if (!Objects.equals(this.project, other.project)) {
return false;
}
if (!Objects.equals(this.personalCard, other.personalCard)) {
return false;
}
return true;
}
}
First I save the Project. It works fine. Then i want to connect it using project_function - so I create project_function set them existing project and personal_card and after trying to persist I get following error:
Caused by: org.postgresql.util.PSQLException: ERROR: column projectfun0_.personalcard does not exist
Position: 8
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:561)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:419)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:304)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82)
... 119 more
So apparently Hibernate does not know projectfun0_.personalcard . But I dont know why. Do you see any error in the entity classes? Or could the error possibly be somewhere else ?
Thank you very much for all your answers :)
EmbeddedId documentation
Relationship mappings defined within an embedded id class are not supported.
So, ProjectFunctionPK should contain only basic mappings, and entity mappings should be done in the entity itself. Here are some related posts
https://stackoverflow.com/a/9760808/4074715
https://stackoverflow.com/a/4692144/4074715

How to set and get values for Composite primary keys and other fields in jpa?

This is my Entity class
#EmbeddedId
private AuthorWorkPKEmbedded embeddedId;
#Column(name = "ColumnA")
private String ColumnA;
public AuthorWorkPKEmbedded getEmbeddedId() {
return embeddedId;
}
public void setEmbeddedId(AuthorWorkPKEmbedded embeddedId) {
this.embeddedId = embeddedId;
}
public String getColumnA() {
return ColumnA;
}
public void setColumnA(String ColumnA) {
this.ColumnA = ColumnA;
}
public AuthorWorkEmbedded() {
}
public AuthorWorkEmbedded(BigInteger bookId,BigInteger authorId) {
this.embeddedId = new AuthorWorkPKEmbedded(bookId, authorId);
}
This is my Embeddable class
#Embeddable
#Column(name = "bookId", nullable = false)
private BigInteger bookId;
#Column(name = "authorId", nullable = false)
private BigInteger authorId;
public AuthorWorkPKEmbedded() {
}
public AuthorWorkPKEmbedded(BigInteger bookId, BigInteger authorId) {
this.bookId = bookId;
this.authorId = authorId;
}
public BigInteger getBookId() {
return bookId;
}
public void setBookId(BigInteger bookId) {
this.bookId = bookId;
}
public BigInteger getAuthorId() {
return authorId;
}
public void setAuthorId(BigInteger authorId) {
this.authorId = authorId;
}
#Override
public int hashCode() {
return bookId.hashCode() + authorId.hashCode();
}
#Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof AuthorWorkPKEmbedded)) {
return false;
}
if (obj == null) {
return false;
}
AuthorWorkEmbedded pk=(AuthorWorkEmbedded) obj;
return (((bookId==((AuthorWorkPKEmbedded)obj).getBookId()))
&&((authorId==((AuthorWorkPKEmbedded)obj).getAuthorId())));
}
This is my main class
how set the composite values and why cant we use generatedvalue for autoincrement purpose and how to retrieve the values from the the database and one more thing where to declare other fields in Entity class or embeddable class and if not how to set and get the values from these 2 classes(entity and embeddable)
EntityTransaction entr = em.getTransaction();
entr.begin();
AuthorWorkPKEmbedded author = new AuthorWorkPKEmbedded();
author.setBookId(BigInteger.ONE);
author.setAuthorId(BigInteger.ONE);
AuthorWorkEmbedded a1=new AuthorWorkEmbedded();
a1.setEmbeddedId(author);
a1.setColumnA("Pirates of carrabian");
boolean successful = false;
try {
em.persist(author);
successful = true;
} finally {
if (successful) {
entr.commit();
} else {
entr.rollback();
}
}
Query query = em.createNamedQuery("AuthorWork.findAll");
List authorList = query.getResultList();
Iterator authorIterator = authorList.iterator();
while (authorIterator.hasNext()) {
author = (AuthorWorkPKEmbedded) authorIterator.next();
System.out.println("Book Id " + author.getBookId() + " " + "Author" + author.getAuthorId() + "");
System.out.println();
}
Use getters and setters for embeddedId .
Query query = em.createNamedQuery("AuthorWork.findAll");
List authorList = query.getResultList();
Iterator authorIterator = authorList.iterator();
while (authorIterator.hasNext()) {
author = (AuthorWorkEmbedded) authorIterator.next();
System.out.println("Book Id " + author.setEmbeddedId().getBookId() + " " + "Author" + author.getEmbeddedId().getAuthorId() + "");
System.out.println(""+author.getColumnA());
}

Override equal method and Bidirectional Relationship

When check instance is equal with other instance, I get
java.lang.StackOverflowError.
Because of there are bidirectional relationship, That's why, my Override equal method call equal() function each other recursively.
Should I remove one check equal condition in override equal method of one side?
What will be better way? Some PG suggest to me to use EqualsBuilder of Apache.
OrderItem.java
public class OrderItem {
private String id;
private Order order;
public OrderItem(String id, Order order) {
this.id = id;
this.order = order;
}
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setOrder(Order order) {
this.order = order;
}
public Order getOrder() {
return order;
}
#Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof OrderItem)) {
return false;
}
final OrderItem other = (OrderItem)object;
if (!(id == null ? other.id == null : id.equals(other.id))) {
return false;
}
if (!(order == null ? other.order == null : order.equals(other.order))) {
return false;
}
return true;
}
}
Order.java
public class Order {
private String id;
private List<OrderItem> orderItemList;
public Order(String id) {
this.id = id;
}
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setOrderItemList(List<OrderItem> orderItemList) {
this.orderItemList = orderItemList;
}
public List<OrderItem> getOrderItemList() {
return orderItemList;
}
#Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof Order)) {
return false;
}
final Order other = (Order)object;
if (!(id == null ? other.id == null : id.equals(other.id))) {
return false;
}
if (!(orderItemList == null ? other.orderItemList == null : orderItemList.equals(other.orderItemList))) {
return false;
}
return true;
}
}
Test
public static void main(String[] args) {
Order order1 = new Order("1");
List<OrderItem> orderItemList = new ArrayList<OrderItem>();
orderItemList.add(new OrderItem("1", order1));
orderItemList.add(new OrderItem("2", order1));
order1.setOrderItemList(orderItemList);
Order order2 = new Order("1");
List<OrderItem> orderItemList2 = new ArrayList<OrderItem>();
orderItemList2.add(new OrderItem("1", order2));
orderItemList2.add(new OrderItem("2", order2));
order2.setOrderItemList(orderItemList2);
if(order1.equals(order2)) {
System.out.println("Equal");
} else {
System.out.println("Not Equal");
}
}
I would rewrite it to use only idattribute for equality check. But this is important: don't forget to override also the hashcode() method if you want your entities behave correctly in Java collections.

Categories