I have a model Parent, which has a list of Children (List
class Parent {
#OneToMany(targetEntity = Child.class, cascade = CascadeType.ALL, mappedBy = "parent")
#JsonManagedReference
private List<Child> tags = new ArrayList<>();
#Column(name = "name")
public String name;
}
class Child {
#Column(name = "name")
public String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "parent_id", nullable = true)
#JsonBackReference
private Parent parent;
}
I select a list of parents (List < Parent> ) with children in EAGER mode.
Now Children can have the same name, but I do not want children with the same name to be more than once in the list.
Any suggestions how have children with the same name only once in the collection?
Here is the sample code using set to remove repeated values. If firstName is present once second entry is ignored. You can modify if according to your needs.
However while this is the answer to the question you have asked please note there is a code smell here . They fact you are having to do this in code while database allows for it is questionable and almost guaranteed a design flaw.
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test
{
private String firstName;
private String lastName;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0 : firstName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Test other = (Test) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
return true;
}
public Test(String firstName, String lastName) {
super();
this.firstName = firstName;
this.lastName = lastName;
}
public static void main(String[] args)
{
List<Test> aList = new ArrayList<Test>();
Test test1 = new Test("Tom","Hardy");
Test test2 = new Test("Tom","Cruise");
Test test3 = new Test("Any","Body");
aList.add(test1);
aList.add(test2);
aList.add(test3);
System.out.println("List values:");
for (Test test : aList)
{
System.out.println(test.firstName + "-"+ test.lastName);
}
Set<Test> alphaSet = new HashSet<Test>(aList);
System.out.println("Set values:");
for (Test test : alphaSet)
{
System.out.println(test.firstName + "-"+ test.lastName);
}
}
}
Related
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);
So, I've got an existing ManyToMany relationship set up in my spring application. It appears that I made a mistake by setting this up using the #ManyToMany annotation, because now I need to add a field to the join table, and this does not appear to be an easy feat.
My structure is shipments and products. The shipment table stores information about who the shipment was sent to, what date it was sent, etc. The product table stores information about the product, who makes it, description, size, etc.
What I failed to consider when building this out was, I will need to track quantity of product shipped when I create a shipment, which should be done on the join table.
I've been working along with this example: https://vladmihalcea.com/the-best-way-to-map-a-many-to-many-association-with-extra-columns-when-using-jpa-and-hibernate/
UPDATE:
I've been working through the example above and have run into an issue with infinite recursive calls between the product and shipment tables. My structure is as follows:
ShipmentProductID.java:
// Package and Imports here
#Embeddable
public class ShipmentProductId
implements Serializable {
#Column(name = "product_id")
private Long productId;
#Column(name = "shipment_id")
private Long shipmentId;
private ShipmentProductId() {}
public ShipmentProductId(
Long productId,
Long shipmentId) {
this.productId = productId;
this.shipmentId = shipmentId;
}
// Getters and Setters here
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
ShipmentProductId that = (ShipmentProductId) o;
return Objects.equals(productId, that.productId) &&
Objects.equals(shipmentId, that.shipmentId);
}
#Override
public int hashCode() {
return Objects.hash(productId, shipmentId);
}
}
ShipmentProduct.java:
// Package and Imports here
#Entity(name = "ShipmentProduct")
#Table(name = "shipment_product")
public class ShipmentProduct {
#EmbeddedId
private ShipmentProductId id;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("productId")
private Product product;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("shipmentId")
private Shipment shipment;
#Column(name = "created_on")
private Date createdOn = new Date();
private ShipmentProduct() {}
public ShipmentProduct(Product product, Shipment shipment) {
this.product = product;
this.shipment = shipment;
this.id = new ShipmentProductId(product.getId(),
shipment.getId());
}
// Getters and Setters here
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
ShipmentProduct that = (ShipmentProduct) o;
return Objects.equals(product, that.product) &&
Objects.equals(shipment, that.shipment);
}
#Override
public int hashCode() {
return Objects.hash(product, shipment);
}
}
Product.java:
// Package and Imports here
#Entity
#Data
#Cache( usage = CacheConcurrencyStrategy.READ_WRITE )
public class Product extends AbstractEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#JsonIgnoreProperties("products")
// Have tried #JsonIgnore as well
#OneToMany(
mappedBy = "product",
orphanRemoval = true
)
private List<ShipmentProduct> shipments = new ArrayList<>();
#NotNull
private Integer quantity;
public boolean isAssociated(Client client){
if( this.client == null || this.client.getId() == null ||
client == null || client.getId() == null ) return
false;
return this.client.getId() == client.getId();
}
public boolean isAssociated(Expression expression){
if( this.expression == null || this.expression.getId() == null
||
expression == null || expression.getId() == null )
return false;
return this.expression.getId() == expression.getId();
}
public void addShipment(Shipment shipment) {
ShipmentProduct shipmentProduct = new ShipmentProduct(this,
shipment);
shipments.add(shipmentProduct);
shipment.getProducts().add(shipmentProduct);
}
public Set<Shipment> getAllShipments(){
Set<Shipment> shipmentList = new HashSet<>();
for (ShipmentProduct shipmentProduct : shipments) {
shipmentList.add(shipmentProduct.getShipment());
}
return shipmentList;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product product = (Product) o;
return Objects.equals(id, product.id);
}
#Override
public String toString(){
return "";
}
#Override
public int hashCode() {
return Objects.hash(id);
}
}
Shipment.java:
// Package and Imports here
#Entity
#Data
#ToString(exclude = {"products", "contacts"})
#EqualsAndHashCode(exclude = {"products", "contacts"})
public class Shipment extends AbstractEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#JsonIgnoreProperties("shipments")
#OneToMany(
mappedBy = "shipment",
orphanRemoval = true
)
private List<ShipmentProduct> products = new ArrayList<>();
public Set<Product> getAllProducts(){
Set<Product> productList = new HashSet<>();
for (ShipmentProduct shipmentProduct : products) {
productList.add(shipmentProduct.getProduct());
}
return productList;
}
public void addProduct(Product product) {
ShipmentProduct shipmentProduct = new ShipmentProduct(product,
this);
products.add(shipmentProduct);
product.getShipments().add(shipmentProduct);
}
public void removeProduct(Product product) {
for (Iterator<ShipmentProduct> iterator = products.iterator();
iterator.hasNext(); ) {
ShipmentProduct shipmentProduct = iterator.next();
if (shipmentProduct.getShipment().equals(this) &&
shipmentProduct.getProduct().equals(product)) {
iterator.remove();
shipmentProduct.getProduct().getShipments().remove(shipmentProduct);
shipmentProduct.setShipment(null);
shipmentProduct.setProduct(null);
}
}
}
public Optional<Product> getProductById(Long productId){
Optional<ShipmentProduct> shipmentProduct =
products.stream().filter(product ->
product.getId().equals(productId)).findFirst();
return productId == null ? Optional.empty() :
Optional.of(shipmentProduct.get().getProduct());
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Shipment shipment = (Shipment) o;
return Objects.equals(id, shipment.id);
}
#Override
public String toString(){
return "";
}
#Override
public int hashCode() {
return Objects.hash(id);
}
}
It seems like I'm getting close, as this appears to be working aside from creating an infinitely large JSON object. I've tried all sorts of combinations of EAGER vs LAZY and JsonIgnore and JsonIgnoreProperties. Any thoughts on how to resolve this? My best guess is some interaction with Lombok, but I have not been able to figure this out.
Looks like I finally figured this out... I removed the following methods:
getAllProducts()
getAllShipments()
and replaced them with:
allProducts()
allShipments()
Having them as getters was always adding them to my return object, and they were not being cut off by #JsonIgnore, or anything else.
Next, I updated ShipmentProduct.java and added #JsonIgnore to both shipment and product, while removing #JsonIgnore and/or #JsonIgnoreProperties from Shipment.java and Product.java.
Then, in order to not receive errors when utilizing allProducts() or allShipments(), I added this to my application.properties file: spring.jackson.serialization.fail-on-empty-beans=false
Once this was all complete, I was also able to keep lombok.
Hopefully this helps somebody else in a similar situation. Also, if anybody has additional constructive criticism, please let me know!
You can keep #ManyToMany annotation, just add the joining table in your db and map it:
#JoinTable(
name = "joining_table",
joinColumns = #JoinColumn(
name = "this_id_in_jt",
referencedColumnName = "this_id"
),
inverseJoinColumns = #JoinColumn(
name = "other_id_in_jt",
referencedColumnName = "other_id"
)
)
#ManyToMany
private List<Other> others;
I am developping a java/jee application in which i am using spring boot and hibernate as frameworks i used hibernate search for full text searching but unfortunately i always got an empty list as result.I am using hibernate version 5.1 and hibernate search orm version 5.5.3.Final.Here is my code :
public void search() {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(this.em);
try {
fullTextEntityManager.createIndexer().startAndWait();
// create native Lucene query unsing the query DSL
// alternatively you can write the Lucene query using the Lucene
// query parser
// or the Lucene programmatic API. The Hibernate Search DSL is
// recommended though
QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(Application.class)
.get();
org.apache.lucene.search.Query luceneQuery = queryBuilder.keyword().wildcard().onField("reference").matching("di*")
.createQuery();
// wrap Lucene query in a javax.persistence.Query
javax.persistence.Query jpaQuery = fullTextEntityManager.createFullTextQuery(luceneQuery,
Application.class);
// execute search
List<Application> result = jpaQuery.getResultList();
System.out.println("your result list is "+result);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
and here is my entity
package biz.picosoft.entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;
#Entity
#Indexed
#Table(name = "application",uniqueConstraints = {#UniqueConstraint(columnNames = "reference")})
public class Application implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)
#Column(name = "reference")
private String reference;
#Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)
#Column(name = "creationDate")
private Date creationDate;
#Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)
#Column(name = "status")
private String status;
#Field(index = Index.YES, analyze = Analyze.NO,store = Store.YES)
#Column(name = "deadLine")
private Date deadLine;
#Field(index = Index.YES, analyze = Analyze.NO,store = Store.YES)
#Column(name = "appType")
private String appType;
#Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)
#Column(name = "projectId")
private Long projectId;
#OneToMany(cascade = CascadeType.ALL)
#JoinTable(name = "App_files", joinColumns = { #JoinColumn(name = "idApp") }, inverseJoinColumns = {
#JoinColumn(name = "idFile") })
private List<FileMetadata> listePiecesJointes = new ArrayList<FileMetadata>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getDeadLine() {
return deadLine;
}
public void setDeadLine(Date deadLine) {
this.deadLine = deadLine;
}
public String getAppType() {
return appType;
}
public void setAppType(String appType) {
this.appType = appType;
}
public Application() {
super();
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
public Long getProjectId() {
return projectId;
}
public void setProjectId(Long projectId) {
this.projectId = projectId;
}
public List<FileMetadata> getListePiecesJointes() {
return listePiecesJointes;
}
public void setListePiecesJointes(List<FileMetadata> listePiecesJointes) {
this.listePiecesJointes = listePiecesJointes;
}
public Application(String reference, Date creationDate, String status, Date deadLine, String appType,Long projectId) {
super();
this.reference = reference;
this.creationDate = creationDate;
this.status = status;
this.deadLine = deadLine;
this.appType = appType;
this.projectId=projectId;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((appType == null) ? 0 : appType.hashCode());
result = prime * result + ((creationDate == null) ? 0 : creationDate.hashCode());
result = prime * result + ((deadLine == null) ? 0 : deadLine.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((projectId == null) ? 0 : projectId.hashCode());
result = prime * result + ((reference == null) ? 0 : reference.hashCode());
result = prime * result + ((status == null) ? 0 : status.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Application other = (Application) obj;
if (appType == null) {
if (other.appType != null)
return false;
} else if (!appType.equals(other.appType))
return false;
if (creationDate == null) {
if (other.creationDate != null)
return false;
} else if (!creationDate.equals(other.creationDate))
return false;
if (deadLine == null) {
if (other.deadLine != null)
return false;
} else if (!deadLine.equals(other.deadLine))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (projectId == null) {
if (other.projectId != null)
return false;
} else if (!projectId.equals(other.projectId))
return false;
if (reference == null) {
if (other.reference != null)
return false;
} else if (!reference.equals(other.reference))
return false;
if (status == null) {
if (other.status != null)
return false;
} else if (!status.equals(other.status))
return false;
return true;
}
#Override
public String toString() {
return "Application [id=" + id + ", reference=" + reference + ", creationDate=" + creationDate + ", status="
+ status + ", deadLine=" + deadLine + ", appType=" + appType + ", projectId=" + projectId + "]";
}
}
I have solved my problem.It was because of subclasses which were not indexed.
Did you make sure your entities are indexed before searching?
If you are using a pre-existing database, or if you initialized your database without using Hibernate ORM APIs (by using SQL directly, or by restoring a dump), your entities are probably not indexed yet.
You should have a look at the mass indexer, which makes it easy to index a lot of entities: https://docs.jboss.org/hibernate/search/5.5/reference/en-US/html_single/#search-batchindex-massindexer
I am in the middle of developing a JHipster project and I've come to a halt due to what I believe to be mapping issues
My Database has several tables, but the two that affect me here are Study and Publication, where they have a Many to Many relationship.
I need to retrieve the collection of Publications where a study can be published, hence Study is the owner of the relationship, but for some reason, Hibernate don't recognise the attributes I map the relation with.
All of this started trying to solve a lazy connection issue, yes I have been through most posts relating this and I have tried everything that made sense to me.
Here the code of Study:
#Audited
#Entity
#Table(name = "Study")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "study")
public class Study implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "num_sites")
private Integer numSites;
#Column(name = "ref")
private String ref;
#Column(name = "study_type")
private String studyType;
#ManyToMany(fetch = FetchType.LAZY)
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#JoinTable(name = "Pub_Study",
joinColumns = #JoinColumn(name="studies_id", referencedColumnName="id"),
inverseJoinColumns = #JoinColumn(name="publications_id", referencedColumnName="id"))
public static Set<Publication> publications = new HashSet<>();
#OneToMany(mappedBy = "study")
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<SiteData> siteDatas = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getNumSites() {
return numSites;
}
public void setNumSites(Integer numSites) {
this.numSites = numSites;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public String getStudyType() {
return studyType;
}
public void setStudyType(String studyType) {
this.studyType = studyType;
}
public static Set<Publication> getPublicationss() {
return publications;
}
public void setPublicationss(Set<Publication> publications) {
this.publications = publications;
}
public Set<SiteData> getSiteDatas() {
return siteDatas;
}
public void setSiteDatas(Set<SiteData> siteDatas) {
this.siteDatas = siteDatas;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Study study = (Study) o;
if(study.id == null || id == null) {
return false;
}
return Objects.equals(id, study.id);
}
#Override
public int hashCode() {
return Objects.hashCode(id);
}
#Override
public String toString() {
return "Study{" +
"id=" + id +
", numSites='" + numSites + "'" +
", ref='" + ref + "'" +
", studyType='" + studyType + "'" +
'}';
}
Here the code of Publication:
#Audited
#Entity
#Table(name = "Publication")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "publication")
public class Publication implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "authors")
private String authors;
#Column(name = "first_author")
private String firstAuthor;
#Column(name = "journal")
private String journal;
#Column(name = "pubMedId")
private Integer pubMedId;
#Column(name = "title")
private String title;
#Column(name = "year_publish")
private Integer yearPublish;
#Version
Integer version;
#ManyToMany(fetch = FetchType.LAZY)
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Study> studies = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAuthors() {
return authors;
}
public void setAuthors(String authors) {
this.authors = authors;
}
public String getFirstAuthor() {
return firstAuthor;
}
public void setFirstAuthor(String firstAuthor) {
this.firstAuthor = firstAuthor;
}
public String getJournal() {
return journal;
}
public void setJournal(String journal) {
this.journal = journal;
}
public Integer getPubMedId() {
return pubMedId;
}
public void setPubMedId(Integer pubMedId) {
this.pubMedId = pubMedId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getYearPublish() {
return yearPublish;
}
public void setYearPublish(Integer yearPublish) {
this.yearPublish = yearPublish;
}
public Set<Study> getStudies() {
return studies;
}
public void setStudies(Set<Study> studys) {
this.studies = studys;
}
public Integer getVersion(){
return version;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Publication publication = (Publication) o;
if(publication.id == null || id == null) {
return false;
}
return Objects.equals(id, publication.id);
}
#Override
public int hashCode() {
return Objects.hashCode(id);
}
#Override
public String toString() {
return "Publication{" +
"id=" + id +
", authors='" + authors + "'" +
", firstAuthor='" + firstAuthor + "'" +
", journal='" + journal + "'" +
", pubMedId='" + pubMedId + "'" +
", title='" + title + "'" +
", yearPublish='" + yearPublish + "'" +
'}';
}
}
Here the Implementation of the query from the Repository package:
public class SiteDataRepositoryImpl implements SiteDataRepositoryCustom{
#PersistenceContext
private EntityManager em;
#Override
public List <SiteDataViewDTO> searchSiteDataByFilter(List<Filter> listFilters) {
TypedQuery<SiteData> query = buildQuery(listFilters);
Hibernate.initialize(Study.publications);
int count=0;
for (Filter filter: listFilters){
if("country".equals(filter.getName()))
query.setParameter(filter.getName(), filter.getQuery());
else if("category".equals(filter.getName()))
query.setParameter(filter.getName(), filter.getQuery());
else if("studyRef".equals(filter.getName()))
query.setParameter(filter.getName(), filter.getQuery());
else if("studyType".equals(filter.getName()))
query.setParameter(filter.getName(), filter.getQuery());
else if("pubMedId".equals(filter.getName()))
query.setParameter(filter.getName(), Integer.valueOf(filter.getQuery()));
count++;
}
List<SiteData> siteDataList = query.getResultList();
List<SiteDataViewDTO> siteDataViewDTOList=new ArrayList<SiteDataViewDTO>();
//temp variables
List<String>tempListTreatments = new ArrayList<String>();
List<String>tempListTitles = new ArrayList<String>();
List<Integer>tempListIdMed = new ArrayList<Integer>();
//filling SiteDataViewDTO list
siteDataList.stream().forEach(sd->{
SiteDataViewDTO temp = new SiteDataViewDTO();
temp.setTypeStudy(sd.getTypeStudy() + "id SiteData: " + sd.getId());
temp.setRef(sd.getStudy().getRef());
temp.setCategory(sd.getCategory().getName());
temp.setUpper95CI(sd.getUpper95CI());
temp.setYearStart(sd.getYearStart());
temp.setYearEnd(sd.getYearEnd());
Set<Publication>setPu = sd.getStudy().getPublicationss();
System.out.println("#################### In the query, size of the Publications List "+setPu.size());
setPu.stream().forEach(sp-> {
tempListTitles.add(sp.getTitle());
tempListIdMed.add(sp.getPubMedId());
});
Set<Treatment>setTr = sd.getTreatments();
/*setTr.stream().forEach(sp-> {
tempListTreatments.add(sp.getTreatmentName());
});*/
temp.setListPubObject(setPu);
temp.setListTreatObject(setTr);
siteDataViewDTOList.add(temp);
});
return siteDataViewDTOList;
}
private TypedQuery<SiteData> buildQuery(List<Filter> listFilters){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<SiteData> cq = cb.createQuery(SiteData.class);
Root<SiteData> siteData = cq.from(SiteData.class);
Join<SiteData, Category> cat = siteData.join("category", JoinType.LEFT);
Join<SiteData, Location> loc = siteData.join("location",JoinType.LEFT);
Join<SiteData, Treatment> tre = siteData.join("treatments",JoinType.LEFT);
Join<SiteData, Study> stu = siteData.join("study",JoinType.LEFT);
Join<Study, Publication> pub = stu.join("publications",JoinType.LEFT);
List<Predicate> predicates = new ArrayList<>();
int index = 0;
for(Filter filter : listFilters){
if("country".equals(filter.getName()))
predicates.add(cb.equal(loc.get("country"), cb.parameter(String.class, filter.getName())));
else if("category".equals(filter.getName()))
predicates.add(cb.equal(cat.get("name"), cb.parameter(String.class, filter.getName())));
else if("studyRef".equals(filter.getName()))
predicates.add(cb.equal(stu.get("ref"), cb.parameter(String.class, filter.getName())));
else if("studyType".equals(filter.getName()))
predicates.add(cb.equal(stu.get("studyType"), cb.parameter(String.class, filter.getName())));
else if("pubMedId".equals(filter.getName()))
predicates.add(cb.equal(pub.get("pubMedId"), cb.parameter(Integer.class, filter.getName())));
index++;
}
cq.where(cb.and(predicates.toArray(new Predicate[0])));
return em.createQuery(cq);
}
}
So, if anyone could throw some light on to this, it would be very helpful!
I Edit to add the main exception it throws:
Caused by: org.hibernate.QueryException: could not resolve property: publications of: org.wwarn.vivax.manager.domain.Study
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1978)
at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:367)
You have a typo in your entity definition: "publicationss" instead of "publications". Since Hibernate uses JavaBeans properties for data access, it complains about getPublications() loss in your definition.
Metamodel preserves you from such typos, consider using it.
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...