Netbeans #JoinColoumns error with auto generated entity class - java

I've creating entities from a data-source using Netbeans 7.4.
And I have an error which arises with all entities which have a composite primary key. The error can be seen below.
I have searched this problem on stack-overflow and its is usually because people have not defined the join columns. but I have this done. I'm also unsure how there is errors in code generated by netbeans.
Here is an image of my MySQL database which I forward engineered to create these entitys:
Any help would be greatly appreciated !
Here is the only the relevant code
Absence entity:
public class Absence implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected AbsencePK absencePK;
#Basic(optional = false)
#NotNull
#Column(name = "idAbsence")
private int idAbsence;
#Basic(optional = false)
#NotNull
#Column(name = "Date")
#Temporal(TemporalType.DATE)
private Date date;
#Size(max = 35)
#Column(name = "type")
private String type;
#Lob
#Size(max = 65535)
#Column(name = "remark")
private String remark;
#JoinColumn(name = "TimeTable_Period", referencedColumnName = "Period", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Timetable timetable;
#JoinColumn(name = "Student_idStudent", referencedColumnName = "idStudent", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Student student;
#JoinColumn(name = "Class_idClass", referencedColumnName = "idClass", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Class class1;
AbsencePK entity:
#Embeddable
public class AbsencePK implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "Class_idClass")
private int classidClass;
#Basic(optional = false)
#NotNull
#Column(name = "Student_idStudent")
private int studentidStudent;
#Basic(optional = false)
#NotNull
#Column(name = "TimeTable_Period")
private int timeTablePeriod;
public AbsencePK() {
}
public AbsencePK(int classidClass, int studentidStudent, int timeTablePeriod) {
this.classidClass = classidClass;
this.studentidStudent = studentidStudent;
this.timeTablePeriod = timeTablePeriod;
}
Error:
Caused by: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b):
org.eclipse.persistence.exceptions.ValidationException
Exception Description: The #JoinColumns on the annotated element [field timetable] from the entity class [class com.fyp.simstest.Absence] 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.
at org.eclipse.persistence.exceptions.ValidationException.incompleteJoinColumnsSpecified(ValidationException.java:1847)
EDIT
TimeTable
#Entity
#Table(name = "timetable")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Timetable.findAll", query = "SELECT t FROM Timetable t"),
#NamedQuery(name = "Timetable.findByPeriod", query = "SELECT t FROM Timetable t WHERE t.timetablePK.period = :period"),
#NamedQuery(name = "Timetable.findByDay", query = "SELECT t FROM Timetable t WHERE t.timetablePK.day = :day"),
#NamedQuery(name = "Timetable.findByClassidClass", query = "SELECT t FROM Timetable t WHERE t.timetablePK.classidClass = :classidClass")})
public class Timetable implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected TimetablePK timetablePK;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "timetable")
private Collection<Absence> absenceCollection;
#JoinColumn(name = "Class_idClass", referencedColumnName = "idClass", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Class class1;
public Timetable() {
}
public Timetable(TimetablePK timetablePK) {
this.timetablePK = timetablePK;
}
TimetablePK
Embeddable
public class TimetablePK implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "Period")
private int period;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "Day")
private String day;
#Basic(optional = false)
#NotNull
#Column(name = "Class_idClass")
private int classidClass;
public TimetablePK() {
}
public TimetablePK(int period, String day, int classidClass) {
this.period = period;
this.day = day;
this.classidClass = classidClass;
}
EDIT TWO

Your diagram indicates the TimeTable table has a primary key composed of three columns (Period, Day, and Class_idClass). You will need to add an annotation to Absence.timeTable that looks something like this:
public class Absence implements Serializable {
...
#JoinColumns[
#JoinColumn(name = "TimeTable_Period", referencedColumnName = "Period", ...),
#JoinColumn(name = "????", referencedColumnName = "Day", ...),
#JoinColumn(name = "Class_idClass", referencedColumnName = "Class_idClass", ...)
]
#ManyToOne(optional = false)
private TimeTable timeTable;
...
}

Consider this:
#JoinColumn(name = "TimeTable_Period", referencedColumnName = "Period")
private Timetable timetable;
You have referenced to the column Period at your Timetable entity. But in the Timetable.java I don't see any field that is mapped with your Period column of your table.
For example:
#Id // as its the primary key!
#Column(name="Period")
private Long period
This should be same for other referenced entities those you have used with your #ManyToOne mapping.

Related

How to use In clause in JPQL query with subquery

I have a entity classes as below
ExportMO.java
#Entity
#Table(name = "DATAEXPORTTEMPLATE")
#NamedQueries({
#NamedQuery(name = "ExportTemplateMO.getTemplatesByUser", query = "SELECT DISTINCT template FROM ExportTemplateMO template " +
"join template.fields exportFields WHERE template.eId IN (SELECT S1.dcid FROM SchoolMO S1 join S1.fields S2 WHERE S2.dcid = :userDCID)")
})
public class ExportMO implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "DATATEMPLATEID", unique = true, nullable = false)
private Long templateId;
#Column(name = "EID", nullable = true)
private Long eId;
#OneToMany(fetch=FetchType.EAGER, mappedBy="templateMO", cascade={CascadeType.ALL}, orphanRemoval=true)
private Set<ExportFieldMO> fields;
}
SchoolMO.java
#Entity
#Table(name = "SCHOOLSTAFF")
public class SchoolMO implements Serializable {
#Id
#Column(name = "DCID", unique = true, nullable = false)
private Long dcid;
#Column(name = "ID", unique = true)
private Long id;
#Column(name = "USERS_DCID", unique = false, nullable = false)
#JoinColumn(name="USERS_DCID",referencedColumnName="USERS_DCID",nullable=false)
private Long users_dcid;
#OneToMany(fetch=FetchType.EAGER, mappedBy="users_dcid", cascade={CascadeType.ALL}, orphanRemoval=true)
private Set<SchoolStaffLeanMO> fields;
}
Can someone help me how to use this using the IN clause for subquery.
If i try to use the same '=' instead of 'IN' i am able to get the results.
Thanks in advance.

The abstract schema type 'User_Book' is unknown

I have a database with several entities, in particular Book and User. Between them there exists a ManyToMany relationship like this:
Book:
#Entity
#Table(name = "Books")
public class Book implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
#Column(name = "bookId", nullable = false, unique = true)
private Long id;
#Column(name = "title", nullable = false)
private String title;
#Column(name = "price", nullable = false)
private int price;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "User_Book",
joinColumns = #JoinColumn(name = "bookId"),
inverseJoinColumns = #JoinColumn(name = "userId"))
private Set<UserAccount> users;
User:
#Entity
#Table(name = "UserAccounts")
public class UserAccount implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
#Column(name = "userId", nullable = false, unique = true)
private Long id;
#Column(name = "username", nullable = false, unique = true)
private String username;
#Column(name = "password", nullable = false)
private String password;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "User_Book",
joinColumns = #JoinColumn(name = "userId"),
inverseJoinColumns = #JoinColumn(name = "bookId"))
Set<Book> purchasedBooks;
Everything works fine, the table User_Book is indeed created in the database. The problem seems to be related to the access of this Table.
For example,
Query query = entityManager.createQuery("SELECT u FROM User_Book u");
keeps telling me the following:
The abstract schema type 'User_Book' is unknown
So, shall I create from scratch the User_Book entity? Will it get automtically populated like now, that is, whenever a user buys a book, will this purchase be recorded in the table?
User_Book is not an entity. Therefore you cannot use createQuery, BUT you can use createNativeQuery to execute a SQL query:
Query query = entityManager.createNativeQuery("SELECT * FROM User_Book");
The result will be List<Object[]>

Deleting entity, which is element of collection and has collection of another entities in Hibernate

I have entity Ad:
#Entity
#NamedQueries({
#NamedQuery(name = "getAllAds",
query = "from Ad"),
#NamedQuery(name = "deleteById",
query = "delete from Ad where id = :id")
})
#FieldMatch(first = "initLanguage",second = "resultLanguage", message = "Languages must be different")
#Table(name = "AD_TEST")
public class Ad implements Serializable{
/**
* Version of this class in production
*/
private static final long serialVersionUID = 1L;
#Id
#SequenceGenerator(name = "standard", initialValue = 1)
#GeneratedValue(generator = "standard", strategy =GenerationType.SEQUENCE)
#Column(name = "AD_ID")
private long id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "CLIENT",nullable = false)
private Client client;
#NotBlank
#Column(name = "AD_NAME", nullable = false)
private String name;
#NotBlank
#Column(name = "AD_DESC",nullable = false,length = 1000)
#Lob
#Size(min = 0, max = 1000)
private String description;
#Column(name = "AD_COUNTRY", nullable = false)
private String country;
#Column(name = "AD_CITY", nullable = false)
private String city;
#NotNull
/**
* Добавить проверку валидности даты
*/
#DateTimeFormat(iso = ISO.DATE,pattern = "dd.MM.yyyy")
#Column(name = "AD_END_DATE",nullable = false)
private LocalDate endDate;
#NotNull
#Column(name = "AD_INIT_LANGUAGE",nullable = false)
#Enumerated(EnumType.STRING)
private Language initLanguage;
#NotNull
#Column(name = "AD_RESULT_LANGUAGE",nullable = false)
#Enumerated(EnumType.STRING)
private Language resultLanguage;
#NotNull
#Column(name = "AD_TRANSLATE_TYPE",nullable = false)
#Enumerated(EnumType.STRING)
private TranslateType translateType;
#Lob
#Column(name = "AD_FILE")
private byte[] file;
#NotNull
#Column(name = "AD_COST",nullable = false,precision = 2)
private double cost;
#NotNull
#Column(name = "AD_CURRENCY",nullable = false)
#Enumerated(EnumType.STRING)
private Currency currency;
#Column(name = "AD_CREATING_DATE",nullable = false)
private LocalDateTime creationDateTime;
#Column(name = "AD_STATUS",nullable = false)
#Enumerated(EnumType.STRING)
private AdStatus status;
#OnDelete(action = OnDeleteAction.CASCADE)
#OneToMany(fetch = FetchType.EAGER,orphanRemoval = true,mappedBy = "ad")
#Cascade(CascadeType.ALL)
private List<ResponsedAd> responsedAds = new ArrayList<>();
public Ad(){}
/*Getters and setters, hashCode and equals*/
Ad is element of collection in Client:
#Entity
#NamedQueries({
#NamedQuery(name = "clientByEmail",
query = "from Client client where client.email = :email")
})
#Table(name = "CLIENT_TEST")
#PrimaryKeyJoinColumn(name= "client_id")
public class Client extends User{
/**
* Version of this class in production
*/
private static final long serialVersionUID = 1L;
#OneToMany(fetch = FetchType.EAGER,orphanRemoval = true,mappedBy = "client")
#Cascade(CascadeType.ALL)
public List<Ad> ads = new ArrayList<>();
#OneToMany(fetch = FetchType.EAGER,orphanRemoval = true,mappedBy = "client")
#Cascade(CascadeType.ALL)
private List<ResponsedAd> responsedAds = new ArrayList<>();
public Client(){}
Ad.class and Client.class have collection of ResponseAd objects:
#Entity
#Table(name = "RESPONSED_AD_TEST")
#NamedQueries({
#NamedQuery(name = "responsedAdsByAd",query="from ResponsedAd where ad = :ad")
})
#Component
public class ResponsedAd {
#Id
#SequenceGenerator(name = "standard", initialValue = 1)
#GeneratedValue(generator = "standard", strategy =GenerationType.SEQUENCE)
private long id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "AD",nullable = false)
private Ad ad;
#Column(nullable = false)
private LocalDateTime dateTimeOfResponse;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "CLIENT")
private Client client;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "TRANSLATOR",nullable = false)
private Translator translator;
#Column(nullable = false)
#Enumerated(EnumType.STRING)
private ResponsedAdStatus status;
public ResponsedAd(){}
I want that after deleting Ad object, all ResponseAd objects from collection were deleted too.
For this I have:
public void deleteById(long id){
Ad ad = get(id);
CopyOnWriteArrayList<ResponsedAd> list = new CopyOnWriteArrayList<>(ad.getResponsedAds());
list.forEach(rad->{
Translator translator = rad.getTranslator();
translator.removeResponsedAd(rad);
ad.removeResponsedAd(rad);
Client client = rad.getClient();
client.removeResponsedAd(rad);
});
Client client = ad.getClient();
client.removeAd(ad);
}
Say me please, how can I do this right? I have very a lot of relationships and when I try do this, I get error
HTTP Status 500 - Request processing failed; nested exception is
org.springframework.dao.InvalidDataAccessApiUsageException:
deleted object would be re-saved by cascade (remove deleted object from associations):
[ua.translate.model.ad.ResponsedAd#102]; nested exception is org.hibernate.ObjectDeletedException:
deleted object would be re-saved by cascade (remove deleted object from associations): [ua.translate.model.ad.ResponsedAd#102]
First of all,
You don't need to use #NotNull if you have nullable = false already declared in #Column(nullable = false).
Second,
What you're trying to do is doing operations in Cascade. Add this cascade = CascadeType.ALL or maybe cascade = CascadeType.REMOVE to your #ManyToOne tags and it should work.
Use this as a reference: JPA #ManyToOne with CascadeType.ALL
My Client object: Client client = rad.getClient(); have two responsedAd object in collection with the same id, therefore even after deleting this responsedAd object: client.removeResponsedAd(rad); client object has one more. And now main question is why this client have two objects with the same id.

Hibernate ORA-02292: integrity constraint (ROOT.SYS_C007062) violated - child record found

I following have hibernate entities:
#Entity
#Table(name = "News")
public final class News implements Serializable, IEntity {
private static final long serialVersionUID = 3773281197317274020L;
#Id
#SequenceGenerator(name = "NEWS_SEQ_GEN", sequenceName = "NEWS_SEQ")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "NEWS_SEQ_GEN")
#Column(name = "NEWS_ID", precision = 0)
private Long newsId; // Primary key
#Column(name = "TITLE")
private String title;
#Column(name = "SHORT_TEXT")
private String shortText;
#Column(name = "FULL_TEXT")
private String fullText;
#Temporal(TemporalType.DATE)
#Column(name = "CREATION_DATE")
private Date creationDate;
#Temporal(TemporalType.DATE)
#Column(name = "MODIFICATION_DATE")
private Date modificationDate;
#OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true)
#JoinColumn(name = "NEWS_ID", updatable = false, referencedColumnName = "NEWS_ID")
#OrderBy("creationDate ASC")
private List<Comment> commentsList;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "NEWS_TAG", joinColumns = { #JoinColumn(name = "NEWS_ID") }, inverseJoinColumns = { #JoinColumn(name = "TAG_ID") })
private Set<Tag> tagSet;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "NEWS_AUTHOR", joinColumns = { #JoinColumn(name = "NEWS_ID") }, inverseJoinColumns = { #JoinColumn(name = "AUTHOR_ID") })
private Set<Author> author;
And the second:
#SequenceGenerator(name = "COMMENTS_SEQ", sequenceName = "COMMENTS_SEQ")
#Entity
#Table(name = "Comments")
public class Comment implements Serializable, IEntity {
private static final long serialVersionUID = 3431305873409011465L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "COMMENTS_SEQ")
#Column(name = "COMMENT_ID", precision = 0)
private Long commentId; // Primary key
#Column(name = "NEWS_ID")
private Long newsId;
#NotEmpty
#NotNull
#Column(name = "COMMENT_TEXT")
private String commentText;
#Temporal(TemporalType.DATE)
#Column(name = "CREATION_DATE")
private Date creationDate;
When I'm trying to remove entity News, I get the exception ORA-02292: integrity constraint (ROOT.SYS_C007062) violated - child record found. So, if I remove the property "updatable = false" it tries to set nullable fields into property Comment. What is my mistake? Please, help.
Thanks.
Because your news records have a one to one or one to many relation with comments. You most likely did not specifcy a CACASDE ON DELETE clause while defining your table. in order to delete entity NEWS you have to make sure that all of its related comments records are deleted or are referencing another NEWS record.
basicaly the definition of the ORA 02292 exception.

JPA - Issues removing child entities on bidirectional mapping

I need to remove a child entity called "SystemParamater" based on the it´s id.
What i was trying to do:
- Begin Tran
SystemParameter param EntityManager.find(SystemParameter.class,<paremeter.id>)
EntityManager.remove(param)
-Commit tran
But the entity was not removed.
What´s the correct way to remove a child entity?
Below, you could find my entities:
SystemParameter:
#Entity
#Table(name = "system_parameters")
#Cacheab le
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SystemParameter extends BasicEntity {
private static final long serialVersionUID = -6416605270912358340L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "paramName", length = 50, nullable = false)
private String paramName;
#Column(name = "paramValue", length = 255, nullable = false)
private String paramValue;
#Column(name = "encrypted", nullable = false)
#Type(type = "yes_no")
private Boolean encrypted = Boolean.FALSE;
#ManyToOne
#JoinColumn(name = "groupId", nullable = false)
private SystemParameterGroup parameterGroup;
}
SystemParameterGroup:
#Entity
#Table(name = "system_parameter_groups", uniqueConstraints = { #UniqueConstraint(columnNames = { "searchKey" }) })
#Cacheable
public class SystemParameterGroup extends BasicEntity {
private static final long serialVersionUID = -1762633144642103487L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name", length = 50, nullable = false)
private String name;
/**
* Description.
*/
#Column(name = "description", length = 255, nullable = false)
private String description;
/**
* Search key.
*/
#Column(name = "searchKey", length = 50, nullable = false)
private String searchKey;
/**
* System parameter list.
*/
#OneToMany(fetch = FetchType.EAGER, mappedBy = "parameterGroup", cascade = CascadeType.ALL, orphanRemoval = true)
#OrderBy("paramName")
private List<SystemParameter> systemParameterList;
}
You have to remove the SystemParameter entity also from the SystemParameterGroup's list of SystemParameter:
systemParameterGroup.getSystemParameterList().remove(systemParameter);
This issue is related to this one.

Categories

Resources