JPA an Java - #JoinColumns error - jpa

I am currently trying to display information requested via JPA 2.0 (eclipselink). I am using glassfish 3.0.1 and netbeans 6.9.1 as IDE. My persistence entities are created under netbeans option "create entity classes from database". My shcema is designed with workbench mysql, and my server is of course mysql. I really cant figure out what creates this #JoinColumns error.
javax.servlet.ServletException: Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [myprojectPU] failed.
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The #JoinColumns on the annotated element [field userInfo] from the entity class [class com.myproject.jpa.UserId] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn.
This part randomly swaps from [field userInfo] from the entity class [class com.myproject.jpa.UserId] to [field userIdList] from the entity class [class com.myproject.jpa.Cell]. So both classes probably have the same issue.
Here are my classes:
#Entity
#XmlRootElement
#Table(name = "user_id", catalog = "workitout", schema = "")
public class UserId implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected UserIdPK userIdPK;
#Basic(optional = false)
#Column(name = "email", nullable = false, length = 45)
private String email;
#Basic(optional = false)
#Column(name = "password", nullable = false, length = 45)
private String password;
#ManyToMany(mappedBy = "userIdList")
private List<Cell> cellList;
#JoinColumn(name = "USER_INFO_id_info", referencedColumnName = "id_info", nullable = false, insertable = false, updatable = false)
#ManyToOne(optional = false)
private UserInfo userInfo;
...
}
#Entity
#XmlRootElement
#Table(name = "user_info", catalog = "workitout", schema = "")
public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected UserInfoPK userInfoPK;
#Basic(optional = false)
#Column(name = "fullName", nullable = false, length = 45)
private String fullName;
#Basic(optional = false)
#Column(name = "city", nullable = false, length = 45)
private String city;
#Basic(optional = false)
#Column(name = "gender", nullable = false, length = 10)
private String gender;
#Basic(optional = false)
#Column(name = "isCoach", nullable = false)
private boolean isCoach;
#Column(name = "age")
private Integer age;
#Column(name = "description", length = 200)
private String description;
#Column(name = "linkImage", length = 45)
private String linkImage;
#Column(name = "friendList", length = 500)
private String friendList;
#Column(name = "coachList", length = 500)
private String coachList;
#JoinColumn(name = "USER_SPORT_id_sport", referencedColumnName = "id_sport", nullable = false, insertable = false, updatable = false)
#ManyToOne(optional = false)
private UserSport userSport;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userInfo")
private List<UserId> userIdList;
...
}
*The first error was solved, but the [field userIdList] from the entity class [class com.myproject.jpa.Cell]. remains. Ive added the code of my cell table:
import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
#Entity
#XmlRootElement
#Table(name = "cell", catalog = "workitout", schema = "")
#NamedQueries({
#NamedQuery(name = "Cell.findAll", query = "SELECT c FROM Cell c"),
#NamedQuery(name = "Cell.findByIdCell", query = "SELECT c FROM Cell c WHERE c.idCell = :idCell"),
#NamedQuery(name = "Cell.findByName", query = "SELECT c FROM Cell c WHERE c.name = :name")})
public class Cell implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#Column(name = "id_cell", nullable = false)
private Integer idCell;
#Basic(optional = false)
#Column(name = "name", nullable = false, length = 45)
private String name;
#ManyToMany
#JoinTable(name = "user_id_has_cell", joinColumns = {
#JoinColumn(name = "cell_id_cell", referencedColumnName = "id_cell", nullable = false)}, inverseJoinColumns = {
#JoinColumn(name = "USER_ID_id", referencedColumnName = "id", nullable = false),
#JoinColumn(name = "USER_INFO_id_info", referencedColumnName = "id_info", nullable = false, insertable = false, updatable = false),
#JoinColumn(name = "USER_SPORT_id_sport", referencedColumnName = "id_sport", nullable = false, insertable = false, updatable = false)
})
private List<UserId> userIdList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "cell")
private List<WorkoutSession> workoutSessionList;
public Cell() {
}
public Cell(Integer idCell) {
this.idCell = idCell;
}
public Cell(Integer idCell, String name) {
this.idCell = idCell;
this.name = name;
}
public Integer getIdCell() {
return idCell;
}
public void setIdCell(Integer idCell) {
this.idCell = idCell;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<UserId> getUserIdList() {
return userIdList;
}
public void setUserIdList(List<UserId> userIdList) {
this.userIdList = userIdList;
}
public List<WorkoutSession> getWorkoutSessionList() {
return workoutSessionList;
}
public void setWorkoutSessionList(List<WorkoutSession> workoutSessionList) {
this.workoutSessionList = workoutSessionList;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idCell != null ? idCell.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 Cell)) {
return false;
}
Cell other = (Cell) object;
if ((this.idCell == null && other.idCell != null) || (this.idCell != null && !this.idCell.equals(other.idCell))) {
return false;
}
return true;
}

Error message describes the problem pretty clearly - UserInfo has a composite key, therefore you need to specify several #JoinColumns, one column for each field of the composite key:
#JoinColumns({
#JoinColumn(...),
#JoinColumn(...)
})
#ManyToOne(optional = false)
private UserInfo userInfo;

From the error message I would try to add the following to your class UserId:
#JoinColumn(name = "USER_INFO_uSERSPORTidsport", referencedColumnName = "uSERSPORTidsport", nullable = false, insertable = false, updatable = false)
#ManyToOne(optional = false)
private UserSport usersport;

Related

Why List(#OneToMany) with JPA in Entity seen PersistentBag

I have two entities as follows Personel.java and PersonelEgitimDurum.java
List personelEgitimDurumList is PersistentBag in Personel as seen follows;
[enter image description here][1]
[1]: https://i.stack.imgur.com/Q3IC2.png
Personel.java as follows;
#Entity
#Table(name="personel")
public class Personel extends BaseEntity {
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="kisi_id")
private Kisi kisi;
#Column(name="personel_tipi",length = 2,nullable = false)
private int personelTipi;
#Column(name="sicil_no",length = 100,nullable = false)
private String sicilNo;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "personel", cascade =CascadeType.ALL,orphanRemoval = true)
private List<PersonelEgitimDurum> personelEgitimDurumList= new ArrayList<PersonelEgitimDurum>();
#Column(name="khk_onay",length = 1)
private int khkOnay;
}
PersonelEgitimDurum.java as follows;
#Entity
#Table(name = "personel_egitim_durum", indexes = {#Index(name = "index_personel_egitim_durum", columnList = "id")})
public class PersonelEgitimDurum extends BaseEntity {
#ManyToOne(cascade=CascadeType.PERSIST,fetch=FetchType.EAGER)
#JoinColumn(name="personel_id",nullable = false, updatable = true)
private Personel personel;
#Column(name = "ogrenim_durumu")
private String ogrenimDurumu;
#Column(name = "okul_id", length = 3)
private Long okulId;
#Column(name = "universite_bolum_id", length = 4)
private Long universiteBolumId;
#Column(name = "mezuniyet_tarihi")
private Date mezuniyetTarihi;
#Column(name = "aciklama", length = 500)
private String aciklama;
}
PersonelServiceImpl.java as follows;
#Service
#Transactional
public class PersonelServiceImpl implements PersonelService {
#Override
public PersonelDTO findPersonelByKimlikNo(String kimlikNo) {
Kisi kisi=kisiDAO.findKisiByKimlikNo(kimlikNo);
Personel personel=personelDao.findPersonelByKisi(kisi);
PersonelDTO personelDTO=mapper.toDto(personel);
return personelDTO;
}
}
Problem is that personel from findPersonelByKimlikNo in PersonelServiceImpl include that personelEgitimDurumList is PersistentBag as image. So mapStruct does not convert entity to dto.
Error log follows;
java.lang.StackOverflowError: null
at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.personelEgitimDurumListToPersonelEgitimDurumDTOList(PersonelMapperImpl.java:159) ~[classes/:na]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.toDto(PersonelMapperImpl.java:53) ~[classes/:na]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.personelEgitimDurumToPersonelEgitimDurumDTO(PersonelMapperImpl.java:144) ~[classes/:na]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.personelEgitimDurumListToPersonelEgitimDurumDTOList(PersonelMapperImpl.java:161) ~[classes/:na]
at org.kktcmeb.personel.kktcmebpersonel.mapper.PersonelMapperImpl.toDto(PersonelMapperImpl.java:53) ~[classes/:na]
Anyone have idea about this situation? Please help
#Entity
#Table(name="personel")
**#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")**
public class Personel extends BaseEntity {
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="kisi_id")
private Kisi kisi;
#Column(name="personel_tipi",length = 2,nullable = false)
private int personelTipi;
#Column(name="sicil_no",length = 100,nullable = false)
private String sicilNo;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "personel", cascade =CascadeType.ALL,orphanRemoval = true)
private List<PersonelEgitimDurum> personelEgitimDurumList= new ArrayList<PersonelEgitimDurum>();
#Column(name="khk_onay",length = 1)
private int khkOnay;
}
ADD to head of entities->#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
#Entity
#Table(name = "personel_egitim_durum", indexes = {#Index(name = "index_personel_egitim_durum", columnList = "id")})
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class PersonelEgitimDurum extends BaseEntity {
#ManyToOne(cascade=CascadeType.PERSIST,fetch=FetchType.EAGER)
#JoinColumn(name="personel_id",nullable = false, updatable = true)
private Personel personel;
#Column(name = "ogrenim_durumu")
private String ogrenimDurumu;
#Column(name = "okul_id", length = 3)
private Long okulId;
#Column(name = "universite_bolum_id", length = 4)
private Long universiteBolumId;
#Column(name = "mezuniyet_tarihi")
private Date mezuniyetTarihi;
#Column(name = "aciklama", length = 500)
private String aciklama;
}

Hibernate error: mappedBy reference an unknown target entity property

I am having an issue in setting up a many to many relationship in my entities. And I don't understand why
failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: cardgame.bean.User.card in cardgame.bean.Card.users
My Entities:
#MappedSuperclass
#Data
public class BaseEntity implements Serializable {
#Id
#Column(name = "id", nullable = false, unique = true)
private String id;
public BaseEntity() {
this.id = UUID.randomUUID().toString();
}
}
My user emtity:
#Data
#Entity
#Table(name = "users")
public class User extends BaseEntity {
#Column(name = "username", nullable = false, unique = true)
private String username;
#Column(name = "uuid", nullable = false)
private String uuid;
#Column(name = "email", nullable = false, unique = true)
private String email;
#OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Card> cards;
#Column(name = "isActive", nullable = false)
private boolean isActive;
}
My card entity:
#Data
#Entity
#Table(name = "cards")
public class Card extends BaseEntity {
#OneToMany(mappedBy = "card")
private List<User> users;
#Column(name = "strength", nullable = false)
private int strength;
#Column(name = "isActive", nullable = false)
private boolean isActive;
}
The users and cards tables have a many-to-many relationship via user_card table:
#Data
#Entity
#Table(name = "user_card")
public class UserCard implements Serializable {
#Id
#ManyToOne
#JoinColumn(name = "user_id", nullable = false)
private User user;
#Id
#ManyToOne
#JoinColumn(name = "card_id", nullable = false)
private Card card;
#Column(name = "cardCount", nullable = false)
private int cardCount;
}
What am i doing incorrect. Please help me

Error in a ManyToMany Relationship on Hibernate-JPA

I have a large DB on MySql Workbench and I'm trying to map the relationship between the entities on Eclipse Mars thanks to Hibernate and the JPA module. The fact is that I receive the error:
"In attribute 'personAddresses', the "mapped by" attribute 'peopleAdd' has an invalid mapping type for this relationship."
This are the entities involved.
1
I've to say that making a forward engineering, Hibernate creating for me an AddressId class, where the composite primary key of Address is mapped. I suspect that the problem could be this, but I'm not certain, can you help me please?
Under I post the code so that it's more clear to understand how the classes are implemented.
#Entity
#IdClass(AddressId.class)
#Table(schema = "YouDroop", name = "Address")
public class Address implements Serializable
{
...
private Collection<Person> peopleAdd = new HashSet<Person>();
#Id
#Column(name = "Address", length = 45, unique = true, nullable = false)
private String address;
#Id
#Column(name = "Number", unique = true, nullable = false)
private int number;
...
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(
name = "PersonHasAddress",
joinColumns = {
#JoinColumn(name = "Address_Address", referencedColumnName = "Address", nullable = false),
#JoinColumn(name = "Address_Number", referencedColumnName = "Number", nullable = false)
},
inverseJoinColumns = {#JoinColumn(name = "Person_Email", referencedColumnName = "Email", nullable = false)}
)
public Collection<Person> getPeopleAddressed(){
return this.peopleAdd;
}
public void setPeopleAddressed(Collection<Person> people){
this.peopleAdd = people;
}
}
public class AddressId implements Serializable
{
private String address;
private int number;
public AddressId(){}
public AddressId(String address, int number) {
super();
this.address = address;
this.number = number;
}
...
}
#Entity
#Table(name = "Person", schema = "YouDroop", uniqueConstraints =
{ #UniqueConstraint(columnNames = "NickName"),
#UniqueConstraint(columnNames = "Password") })
public class Person implements Serializable
{
...
private Collection<Address> addresses = new HashSet<Address>();
...
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "peopleAdd")
public Collection<Address> getPersonAddresses(){
return this.addresses;
}
public void setPersonAddresses(Collection<Address> addresses){
this.addresses = addresses;
}
}
Since you placed you #ManyToMany annotation on your getter method (or property) and not on the field. The mappedBy attribute should reference the property instead and not the field.
#ManyToMany
public Collection<Person> getPeopleAddressed() {
...
}
So your mappedBy attribute should have been
#ManyToMany(mappedBy="peopleAddressed")
public Collection<Address> getPersonAddresses() {
...
}

Bean validation succeeded but failed on jpa merge method

I want to persist an entity(MyEntity) with merge method. This entity have some beans validation.
public class MyEntity extends AbstractEntity {
#Basic(optional = false)
#Column(name = "city", length = 255, nullable = false)
#NotNull
#NotEmpty(message = "{myentity.validation.size.name}")
private String city;
private String number;
#Basic(optional = false)
#Column(name = "zipcode", length = 255, nullable = false)
#NotNull
private String zipcode;
private String phoneNumber;
#Email(message = "{myentity.validation.conform.email}")
#Size(min = 2, max = 100, message = "{myentity.validation.size.email}")
private String email;
private String website;
private String gpsLocation;
#ElementCollection()
#CollectionTable(name = "translation_poi", joinColumns = #JoinColumn(name = "point_id"))
#MapKeyJoinColumn(name = "locale")
#NotEmpty
private Map<Locale, MyEntityI18n> translations = new HashMap<>();
}
#Embeddable
public class MyEntityI18n implements java.io.Serializable {
#Basic(optional = false)
#Column(name = "name", length = 255, nullable = false)
#NotNull
#NotEmpty(message = "{myentity.validation.size.name}")
private String name;
#Column(name = "comment", length = 1200)
private String comment;
#Column(name = "short_description", length = 1200)
private String shortDescription;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The merge succeeded on an existing entity value but with a new entity the merge failed despite the fact that the following validation succeeded.
private boolean validate(MyEntity poi) {
boolean result = true;
Set<ConstraintViolation<MyEntity>> constraintViolations = validator.validate(poi);
if (constraintViolations.size() > 0) {
result = false;
for (ConstraintViolation<MyEntity> constraints : constraintViolations) {
FacesContext context = FacesContext.getCurrentInstance();
String message = constraints.getPropertyPath() + " " + constraints.getMessage();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, constraints.getMessage(), message));
}
}
return result;
}
Try to add a #Valid to MyEntity.translations property. I think that your validation method hasn't take account the MyEntityI18n.name validation.
About merge fails, Do you have a not-null DB constraint on the MyEntityI18n.name field?
Good luck!

Insert object with composite primary key

I need help with this. With code is more clear, this is my function to persist:
public String finalizarCompra() {
Pedido pedido = new Pedido();
pedido.setEstado("almacen");
pedido.setFechaVenta(new Date());
pedido.setIdUsuario(loginBean.getUsuario());
Producto p;
Integer i;
DetPedido detPedido;
List<DetPedido> lista = new ArrayList<>();
for (Map.Entry e : productos.entrySet()) {
detPedido = new DetPedido();
p = (Producto) e.getKey();
i = (Integer) e.getValue();
detPedido.setProducto(p);
detPedido.setCantidad(i);
detPedido.setPrecioUnidad(p.getPrecioUnidad());
detPedido.setPedido(pedido);
lista.add(detPedido);
detPedidoBean.insert(detPedido);
}
pedido.setDetPedidoCollection(lista);
pedidoBean.insert(pedido);
return "";
}
This is my Pedido Entity:
#Entity
public class Pedido implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "ID_PEDIDO")
private Integer idPedido;
#Basic(optional = false)
#NotNull
#Column(name = "FECHA_VENTA")
#Temporal(TemporalType.TIMESTAMP)
private Date fechaVenta;
#Column(name = "FECHA_ENVIO")
#Temporal(TemporalType.TIMESTAMP)
private Date fechaEnvio;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 50)
#Column(name = "ESTADO")
private String estado;
#JoinColumn(name = "ID_USUARIO", referencedColumnName = "ID_USUARIO")
#ManyToOne(optional = false)
private Usuario idUsuario;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "pedido")
private Collection<DetPedido> detPedidoCollection;
// Getters and Setters //
This is my DetPedido Entity:
#Entity
public class DetPedido implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected DetPedidoPK detPedidoPK;
#Basic(optional = false)
#NotNull
#Column(name = "CANTIDAD")
private Integer cantidad;
#Basic(optional = false)
#NotNull
#Column(name = "PRECIO_UNIDAD")
private Double precioUnidad;
#JoinColumn(name = "ID_PRODUCTO", referencedColumnName = "ID_PRODUCTO", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Producto producto;
#JoinColumn(name = "ID_PEDIDO", referencedColumnName = "ID_PEDIDO", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Pedido pedido;
// Getters and Setters //
And this is my DetPedidoPK:
#Embeddable
public class DetPedidoPK implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "ID_PEDIDO")
private Integer idPedido;
#Basic(optional = false)
#NotNull
#Column(name = "ID_PRODUCTO")
private Integer idProducto;
// Getters and Setters //
The Entities ara generated automatically from the Database, also DetPedidoPK, and now I don't know how to save a Pedido. I tried with the code above, but it doesn't work.
Can anybody help me?
Greetings.
If you are using JPA 1.0 and this entity model, then you will need to persist and flush both Producto and Pedido instances to have their IDs assigned before you can persist the DetPedido instance that will reference them. Once that is done, you will need to manually set the id values in DetPedido's DetPedidoPK instance so that they match the referenced Producto and DetPedido key values. You cannot insert DetPedido without the DetPedidoPK values having been set.
JPA 2.0 supports derived IDs, which allows marking the relationship as either #ID or #MapsId, indicating that the ID values should be pulled from the joincolumn associated to the relationship. In this case, it would become:
#ManyToOne(optional = false)
#MapsId("idProducto")
private Producto producto;
#ManyToOne(optional = false)
#MapsId("idPedido")
private Pedido pedido;
If you wanted, you could do away with the embeddable within DetPedido and just mark the relationships as the #Id, and because it is composite you would use the DetPedidoPK as the PK class.