JPA Mapping Error -not provided sufficient metadata in your id class - java

I am trying to do mapping in JPA.
#Entity
public class Auction {
#Id
private Integer auctionId;
#OneToMany(mappedBy="auctionId")
#MapKey(name="auctionParamId")
private Map<AuctionParam, AuctionParamValue> values;
}
#Entity
public class AuctionParam {
#Id
private Integer auctionParamId;
private String description;
}
#Entity
public class AuctionParamValue {
#EmbeddedId
private AuctionParamValuePK pk;
private String value;
}
#Embeddable
public class AuctionParamValuePK {
#ManyToOne
#JoinColumn(name="auctionId")
private Auction auction;
#ManyToOne
#JoinColumn(name="auctionParamId")
private AuctionParam auctionParam;
}
Showing an error:-
.Error-Details:-Exception Description:
Entity [class
com.eaportal.domain.AuctionParamValue]
uses [class
com.eaportal.domain.AuctionParamValuePK]
as embedded id class
whose access-type
has been determined as [FIELD].
But
[class
com.eaportal.domain.AuctionParamValuePK]
does not define any [FIELD]. It is
likely that you have not provided
sufficient metadata in your id class
[class
com.eaportal.domain.AuctionParamValuePK].
If you come up with a solution please let me know.
Thanks in Advance
Tushar

You cannot use an EmbeddedId with relationships. Use an IdClass.
#Entity
#IdClass(AuctionParamValuePK.class)
public class AuctionParamValue {
#Id
#ManyToOne
#JoinColumn(name="auctionId")
private Auction auction;
#Id
#ManyToOne
#JoinColumn(name="auctionParamId")
private AuctionParam auctionParam;
#Basic
private String value;
}
public class AuctionParamValuePK {
private int auction;
private int auctionParam;
}

I think there are some errors in your Auction class. This is how I think it should look
#Entity
public class Auction {
#Id
private Integer auctionId;
#OneToMany(mappedBy="auction") // not auctionId
#MapKey(name="auctionParam") // not auctionParamId
private Map<AuctionParam, AuctionParamValue> values;
}
(The annotation values have to correspond with fields (or properties), not with columns)

Related

Link between entities with JPA

I'm creating a java web application, and for the backend, I use JPA and a h2 database.
I have for the moment one class called Secteur and one class called Bassin.
In my conception, one Secteur can have many Bassin, but one Bassin can have just one Secteur. Moreover it's not possible to create a Bassin if there is no Secteur already created (because one Bassin is already linked to a Secteur).
This is the Secteur class :
#Entity
public class Secteur {
#Id
#GeneratedValue
private int id;
private String nom;
...
}
And this is the Bassin class :
#Entity
public class Bassin {
#Id
#GeneratedValue
private int id;
private String nomBassin;
private int tailleMax;
private int tailleUtilise;
private Date dernierNetoyage;
private String etatBassin;
private int idSecteur;
...
}
After a lot of research, I had seen that different annotation exist like #ManyToOne, #OneToMany, etc. But I don't know how to use them in order to resolve my problem.
1) Can you help me please ?
2)Moreover if I use these annotations can I remove "private int idSecteur" ?
Thank you in advance for your help !
The Secteur entity mapping should be:
#Entity
public class Secteur {
#Id
#GeneratedValue
private int id;
private String nom;
#ManyToOne
#JoinColumn(name="secteur_id", nullable=false)
private Bassin bassin;
}
The bassin entity mapping should be:
#Entity
public class Bassin {
#Id
#GeneratedValue
private int id;
private String nomBassin;
private int tailleMax;
private int tailleUtilise;
private Date dernierNetoyage;
private String etatBassin;
#OneToMany(mappedBy="bassin")
    private Set<Secteur> secteurs;
}
Note that secteur_id in the annotation refers to the name of secteur id column in database.
I advise you to take a look to this more complete reference

JPA Problem, Using Parent Entity's Primary Key for Child's Entity's Primary Key

I'm currently developing my project under Spring with JPA.
First off, here is my database schema for the background information
So, I'm undergoing difficulties when I try to use history_id of HISTORY as the primary key of TAG. It gives me ...Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: This class [class com.wrapsody.demo.HistoryTag] does not define an IdClass error.
So I added #IdClass(HistoryTag.HistoryTagAssignId.class) in my HistoryTag.java
#NoArgsConstructor(access = AccessLevel.PROTECTED) #Data #Entity
#IdClass(HistoryTag.HistoryTagAssignId.class)
public class HistoryTag implements Serializable {
#Id
#ManyToOne
private History history;
#Column
private String tagName;
#Builder
public HistoryTag(String tagName) {
this.tagName = tagName;
}
#NoArgsConstructor
public static class HistoryTagAssignId implements Serializable {
private History history;
public HistoryTagAssignId(History history) {
this.history = history;
}
}
}
For the reference, this is History.java
#NoArgsConstructor(access = AccessLevel.PROTECTED)
#Data
#Entity
public class History {
#Id
#GeneratedValue
private Long historyId;
#Column
private String historyMaterName;
#Column
private String historyFreeSetName;
History(String historyMaterName, String historyFreeSetName) {
this.historyMaterName = historyMaterName;
this.historyFreeSetName = historyFreeSetName;
}
}
Any guidance towards solving this error msg is appreciated.
Thanks!
For tag table you dont need entity class. Its duable in History entity with:
#ElementCollection
#CollectionTable(
name="TAG",
joinColumns=#JoinColumn(name="HISTORY_ID")
)
#Column(name="TAG_NAME")
List<String> tags;
https://en.wikibooks.org/wiki/Java_Persistence/ElementCollection#Basic_Collections

Loaded Entity has parent but has no #Parent

I have the following schema, using Objectify
#Entity
public class Book{
#Id
private long id;
private Key<Page> pages;
…
}
#Entity
public class Page{
#Id
private String id;
…
public Page(Book book,int pageNumber){
this.id = book.getId()+””+pageNumber;
…
}
}
I am getting the complaint
com.googlecode.objectify.LoadException: Error loading
Book(1401058017250)/Page("14010580172505639445604728832"): Loaded
Entity has parent but com.company.api.db.Page has no #Parent
Caused by: java.lang.IllegalStateException: Loaded Entity has parent
but com.company.api.db.Page has no #Parent
I am coming from Eclipse and Datanucleus and in that framework the code was
#Entity
public class Book{
#Id
private long id;
private List<Page> pages;
…
}
#Entity
public class Page{
#Id
private Key key;
…
public Page(Book book,int pageNumber){
this.key = createKey(book.getId(),pageNumber);
…
}
private Key createKey(long bookId, long pageNumber) {
Key bookKey = KeyFactory.createKey(Book.class.getSimpleName(), bookId);
Key key = KeyFactory.createKey(bookKey, Page.class.getSimpleName(), bookId + "" + pageNumber);
return key;
}
}
Whether it was the best code or not, it used to work. So anyway, I am migrating to Objectify and Android Studio. How do I rewrite this schema so I stop getting the error? If someone does know the answer, please just copy and paste my code snippet and make the appropriate edits.
In your old code, you're marking bookKey as the parent entity. In new code, you need to have:
#Parent
Key<Book> parentBook;
Your new classes should be:
#Entity
public class Book{
#Id
private long id;
private List<Key<Page>> pages;
…
}
#Entity
public class Page{
#Id
private String id;
#Parent
Key<Book> parentBook;
…
public Page(long bookId, int pageNumber){
this.id = bookId + ”” +pageNumber;
this.parentBook = Key.create(Book.class, bookId);
…
}
}
Read more about Keys and objectify here: https://code.google.com/p/objectify-appengine/wiki/Concepts#Keys

Javax validation error when save a class which include ManyToOne relationship

I want to save Tesis class using entityManager.persist() method but I get following error.
Caused by: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: thymeleafexamples.layouts.acenta.Acenta.
#Entity
public class Tesis {
public Tesis(){
}
public Tesis(String adi, Acenta acenta) {
this.adi = adi;
this.acenta = acenta;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotEmpty
private String adi;
#NotEmpty
#ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
#JoinColumn(name="acenta_id")
private Acenta acenta;
//GETTERS AND SETTERS
}
/////////////////////////////////////////////////////////////////////
#SuppressWarnings("serial")
#Entity
public class Acenta implements java.io.Serializable {
public Acenta(String adi) {
this.adi = adi;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotEmpty
private String adi;
#OneToMany(mappedBy="acenta")
private Set<Tesis> tesiss;
}
According to Hibernate Validator's API org.hibernate.validator.constraints.NotEmpty annotation
"asserts that the annotated string, collection, map or array is not
null or empty"
Based on the above definition Acenta type is not a valid type to check. You may consider using javax.validation.constraints.NotNull annotation instead as it's valid for all types and moreover not vendor specific.

Hibernate. Repeated column when mapping #IdClass annotated entity with composite key

I've ran into problem with composite primary key handling by Hibernate as a JPA provider.
My entities look like below
// Entity class
#Entity
#IdClass(ExternalMatchPK.class)
#Table(name = "external_match")
public class ExternalMatch {
#Id
#Column(name = "place_id")
private Integer placeId;
#Id
#Column(name = "external_object_id")
private Integer externalObjectId;
// ... Other stuff here
}
// Key class
public class ExternalMatchPK implements Serializable {
private Integer placeId;
private Integer externalObjectId;
}
Looks pretty simple yet no matter what I do I keep getting the following exception (lines are splitted for readability):
org.hibernate.MappingException:
Repeated column in mapping for entity: ExternalMatch
column: external_object_id (should be mapped with insert="false" update="false")
I've tried placing annotation on entity class fields and key class fields together as well as separately, moving all annotations from fields to getters on each one of the classes, using key calss as #Embeddable and putting it into the entity class with #EmbeddedId. Nothing seems to work.
This case seems trivial so maybe it's something wrong with our setup but I can't even imagine where to look for the issue.
Any advice is much appreciated.
It appears that I shot myself in the foot with this.
The issue was that I had a biderectional mapping between ExternalMatch and ExternalObject I forgot about trying to replace the actual entity with its integer id.
So changing
// Entity class
#Entity
#IdClass(ExternalMatchPK.class)
#Table(name = "external_match")
public class ExternalMatch {
#Id
#Column(name = "place_id")
private Integer placeId;
#Id
#Column(name = "external_object_id")
private Integer externalObjectId;
// ... Other stuff here
}
// Key class
public class ExternalMatchPK implements Serializable {
private Integer placeId;
private Integer externalObjectId;
}
// Related entity class
#Entity
#Table(name = "external_object")
public class ExternalObject extends AbstractNameableEntity {
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name = "external_object_id", nullable = false)
private List<ExternalMatch> matches;
// ...
}
to reprsent actual mappings like this
// Entity class
#Entity
#IdClass(ExternalMatchPK.class)
#Table(name = "external_match")
public class ExternalMatch {
#Id
#ManyToOne
#JoinColumn(name = "external_object_id", referencedColumnName = "id")
private ExternalObject externalObject;
#Id
#ManyToOne
#JoinColumn(name = "place_id")
private Poi place;
// ... Other stuff here
}
// Key class
public class ExternalMatchPK implements Serializable {
private Poi place;
private ExternalObject externalObject;
}
// Related entity class
#Entity
#Table(name = "external_object")
public class ExternalObject extends AbstractNameableEntity {
#OneToMany(cascade = CascadeType.ALL, mappedBy = "externalObject")
private List<ExternalMatch> matches;
// ...
}
resolved the repeated mapping issue yet leaving us with all the familiar troubles a biderectional mapping creates :)

Categories

Resources