Bidrectional #OneToMany relation with a composite key - jpa

I have been trying to create a bidirectional #OneToMany relation with composite keys but some pieces are missing or wrong.
I have a draft entity which holds a list of sub draft entities.
Here is what I got:
#Entity
#Table(name = "draft")
#IdClass(Pk.class)
public class Draft {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
protected Long id;
#Id
protected Integer rev;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "draft")
List<SubDraft> subDrafts = new ArrayList<SubDraft>();
// getters / setters omitted
}
#Entity
#Table(name = "sub_draft")
#IdClass(PK.class)
public class DraftToDoDAO {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
protected Long id;
#Id
protected Integer rev;
#ManyToOne(fetch = FetchType.LAZY)
#PrimaryKeyJoinColumns({
#PrimaryKeyJoinColumn(name = "draft_id", referencedColumnName = "id"),
#PrimaryKeyJoinColumn(name = "draft_rev", referencedColumnName = "rev")
})
protected DraftDAO draft;
// getters / setters omitted
}
public class PK implements Serializable {
protected Long id;
protected Integer rev;
public PK() {
}
public PK(Long id, Integer rev) {
this.id = id;
this.rev = rev;
}
public Long getId() {
return id;
}
public Integer getRev() {
return rev;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((rev == null) ? 0 : rev.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;
MetaDataDAO other = (MetaDataDAO) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (rev == null) {
if (other.rev != null)
return false;
} else if (!rev.equals(other.rev))
return false;
return true;
}
}
I have no problems saving a draft with a list of sub drafts but the relation is not created both ways.
In the sub draft table the SchemaTool (DataNucleus) creates a column named draft_id but it is empty. And I wonder why it is not creating the columns I specified (draft_id, draft_rev) and settles the relation there.
I have search a lot for an answer but just can not get thing to work.
Your help is appreciated!
Thanks.
EDIT!
Here is the actual persistence code:
public Draft create(Draft draft, SubDraft subDraft) {
EntityManager em = PersistenceHelper.getEntityManager();
draft.setCreated(Calendar.getInstance());
// This should do it
draft.setSubDraft(subDraft);
subDraft.setDraft(draft);
em.persist(draft);
em.close();
return draft;
}

Some where along the line of code this subDraft attribute was nilled and therefore is did not work.

Related

Rest API order by name

I'm trying to create my own REST API and I'm having trouble trying to order my data by name. currently, I am able to display all the data from the styles table, however, I wish to sort them alphabetically.
I was able to do a filter by extracting the year from the date and checking if that was in the database, this is shown in
public List<Beers> getAllBeersByYear(int year) {
EntityManager em = DBUtil.getEMF().createEntityManager();
List<Beers> list = null;
List<Beers> beersToRemove = new ArrayList<>();
try {
list = em.createNamedQuery("Beers.findAll", Beers.class)
.getResultList();
if (list == null || list.isEmpty()) {
list = null;
}
} finally {
em.close();
}
Calendar cal = Calendar.getInstance();
for (Beers beer : list) {
cal.setTime(beer.getLastMod());
if (cal.get(Calendar.YEAR) != year) {
beersToRemove.add(beer);
}
}
list.removeAll(beersToRemove);
return list;
}
the controller is
#GetMapping(produces=MediaType.APPLICATION_JSON_VALUE)
public List<Styles> GetAllStyles() {
return service.getAllStyles();
}
would it be possible to do something similar to the service and controller where instead of filtering the data, it can sort by the name of a column
the service is
public List<Styles> getAllStyles() {
EntityManager em = DBUtil.getEMF().createEntityManager();
List<Styles> list = null;
try {
list = em.createNamedQuery("Styles.findAll", Styles.class)
.getResultList();
if (list == null || list.isEmpty()) {
list = null;
}
} finally {
em.close();
}
return list;
}
the JPA I am using is
#Entity
#Table(name = "styles")
#NamedQueries({
#NamedQuery(name = "Styles.findAll", query = "SELECT s FROM Styles s"),
#NamedQuery(name = "Styles.findById", query = "SELECT s FROM Styles s WHERE s.id = :id"),
#NamedQuery(name = "Styles.findByCatId", query = "SELECT s FROM Styles s WHERE s.catId = :catId"),
#NamedQuery(name = "Styles.findByStyleName", query = "SELECT s FROM Styles s WHERE s.styleName = :styleName"),
#NamedQuery(name = "Styles.findByLastMod", query = "SELECT s FROM Styles s WHERE s.lastMod = :lastMod")})
public class Styles implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Column(name = "cat_id")
private int catId;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#Column(name = "style_name")
private String styleName;
#Basic(optional = false)
#NotNull
#Column(name = "last_mod")
#Temporal(TemporalType.TIMESTAMP)
private Date lastMod;
public Styles() {
}
public Styles(Integer id) {
this.id = id;
}
public Styles(Integer id, int catId, String styleName, Date lastMod) {
this.id = id;
this.catId = catId;
this.styleName = styleName;
this.lastMod = lastMod;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public int getCatId() {
return catId;
}
public void setCatId(int catId) {
this.catId = catId;
}
public String getStyleName() {
return styleName;
}
public void setStyleName(String styleName) {
this.styleName = styleName;
}
public Date getLastMod() {
return lastMod;
}
public void setLastMod(Date lastMod) {
this.lastMod = lastMod;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Styles)) {
return false;
}
Styles other = (Styles) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "Service.Styles[ id=" + id + " ]";
}
}
You can use #OrderBy annotation
https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/order-by-annotation.html
Just create another query:
#NamedQuery(name = "Styles.findAll", query = "SELECT s FROM Styles s ORDER BY s.name")
And why are you filtering in the code when you can add a query with a where condition?

JPQL count Parent Objects on Multiple Children Match in OneToMany Relationship

In a JavaEE JPA web application, Feature entity has bidirectional ManyToOne relationship with Patient Entity. I want to write a query to count the number of Patients who have one or more matching criteria features. I use EclipseLink as the Persistence Provider.
For example, I want to count the number of patients who have a feature with 'variableName' = 'Sex' and 'variableData' = 'Female' and another feature with 'variableName' = 'smoking' and 'variableData' = 'yes'.
How can I write a JPQL query to get the count of patients?
After the first answer, I tried this Query does not give any results as expected.
public void querySmokingFemales(){
String j = "select count(f.patient) from Feature f "
+ "where ((f.variableName=:name1 and f.variableData=:data1)"
+ " and "
+ " (f.variableName=:name2 and f.variableData=:data2))";
Map m = new HashMap();
m.put("name1", "sex");
m.put("data1", "female");
m.put("name2", "smoking");
m.put("data2", "yes");
count = getFacade().countByJpql(j, m);
}
The Patient entity is as follows.
#Entity
public class Patient implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
#OneToMany(mappedBy = "patient")
private List<Feature> features;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Patient)) {
return false;
}
Patient other = (Patient) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entity.Patient[ id=" + id + " ]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Feature> getFeatures() {
return features;
}
public void setFeatures(List<Feature> features) {
this.features = features;
}
}
This is the Feature Entity.
#Entity
public class Feature implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String variableName;
private String variableData;
#ManyToOne
private Patient patient;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Feature)) {
return false;
}
Feature other = (Feature) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entity.Feature[ id=" + id + " ]";
}
public String getVariableName() {
return variableName;
}
public void setVariableName(String variableName) {
this.variableName = variableName;
}
public String getVariableData() {
return variableData;
}
public void setVariableData(String variableData) {
this.variableData = variableData;
}
public Patient getPatient() {
return patient;
}
public void setPatient(Patient patient) {
this.patient = patient;
}
}
For single feature counts you can use this
select count(f.patient) from Feature f where f.variableName=:name and f.variableData:=data
Two feature counts
select count(distinct p) from Patient p, Feature f1, Feature f2
where
p.id=f1.patient.id and p.id=f2.patient.id and
f1.variableName=:name1 and f1.variableData:=data1 and
f2.variableName=:name2 and f2.variableData:=data2
Multiple feature counts solution is a bit tricky. org.springframework.data.jpa.domain.Specification can be used
public class PatientSpecifications {
public static Specification<Patient> hasVariable(String name, String data) {
return (root, query, builder) -> {
Subquery<Fearure> subquery = query.subquery(Fearure.class);
Root<Fearure> feature = subquery.from(Fearure.class);
Predicate predicate1 = builder.equal(feature.get("patient").get("id"), root.get("id"));
Predicate predicate2 = builder.equal(feature.get("variableName"), name);
Predicate predicate3 = builder.equal(feature.get("variableData"), data);
subquery.select(operation).where(predicate1, predicate2, predicate3);
return builder.exists(subquery);
}
}
}
Then your PatientRepository have to extend org.springframework.data.jpa.repository.JpaSpecificationExecutor<Patient>
#Repository
public interface PatientRepository
extends JpaRepository<Patient, Long>, JpaSpecificationExecutor<Patient> {
}
Your service method:
#Service
public class PatientService {
#Autowired
PatientRepository patientRepository;
//The larger map is, the more subqueries query would involve. Try to avoid large map
public long countPatiens(Map<String, String> nameDataMap) {
Specification<Patient> spec = null;
for(Map.Entry<String, String> entry : nameDataMap.entrySet()) {
Specification<Patient> tempSpec = PatientSpecifications.hasVariable(entry.getKey(), entry.getValue());
if(spec != null)
spec = Specifications.where(spec).and(tempSpec);
else spec = tempSpec;
}
Objects.requireNonNull(spec);
return patientRepository.count(spec);
}
}
We also handled same situation for two feature and after extracting the IDs, we used a nested loops after and counting the number of common count. It was resource intensive and this two feature query in the answer helped a lot.
May need to redesign the Class Structure so that querying is easier.

Spring Boot JPA Bulk insert

I have 3 Entities Parent,Child,SubChild. Parent is a parent of Child and Child is a parent of SubChild. I need to insert around 700 objects of Parent. Parent can have 50 Objects of Child. Child can have 50 objects of SubChild.
I tried normal repository.save(ListOfObjects) it takes approx 4mins.
Then I tried using entity manager's persist, flush and clear based on batch size(500). This also took approx 4 mins.
There wasn't much difference in performance. Please suggest a best way to insert such a high amount of data efficiently.
Parent
#Entity
public class Parent {
#Id #GeneratedValue(strategy= GenerationType.AUTO)
private Long parentId;
private String aaa;
private String bbb;
private String ccc;
#Version
private Long version;
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent", fetch = FetchType.LAZY)
#JoinColumnsOrFormulas({
#JoinColumnOrFormula(column=#JoinColumn(name="parentId",referencedColumnName="parentId",nullable=false))})
private List<Child> childs = new ArrayList<>();
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public String getAaa() {
return aaa;
}
public void setAaa(String aaa) {
this.aaa = aaa;
}
public String getBbb() {
return bbb;
}
public void setBbb(String bbb) {
this.bbb = bbb;
}
public String getCcc() {
return ccc;
}
public void setCcc(String ccc) {
this.ccc = ccc;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
public List<Child> getChilds() {
return childs;
}
public void setChilds(List<Child> childs) {
this.childs = childs;
}
}
Child
#Entity
public class Child {
#Id #GeneratedValue(strategy= GenerationType.AUTO)
private Long childId;
private String ddd;
private String ccc;
private Integer eee;
#OneToMany(cascade = CascadeType.ALL,orphanRemoval = true, mappedBy = "child", fetch = FetchType.LAZY)
#JoinColumnsOrFormulas({
#JoinColumnOrFormula(column = #JoinColumn(name = "childId", referencedColumnName = "childId", nullable = false)) })
private List<SubChild> subChilds = new ArrayList<>();
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumnsOrFormulas({
#JoinColumnOrFormula(column= #JoinColumn( name="parentId",referencedColumnName="parentId",nullable=false))
})
private Parent parent;
public Long getChildId() {
return childId;
}
public void setChildId(Long childId) {
this.childId = childId;
}
public String getDdd() {
return ddd;
}
public void setDdd(String ddd) {
this.ddd = ddd;
}
public String getCcc() {
return ccc;
}
public void setCcc(String ccc) {
this.ccc = ccc;
}
public Integer getEee() {
return eee;
}
public void setEee(Integer eee) {
this.eee = eee;
}
public List<SubChild> getSubChilds() {
return subChilds;
}
public void setSubChilds(List<SubChild> subChilds) {
this.subChilds = subChilds;
}
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
SubChild
#Entity
public class SubChild {
#Id #GeneratedValue(strategy= GenerationType.AUTO)
private Long subChildId;
private String fff;
private String ggg;
private Integer hhh;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumnsOrFormulas({
#JoinColumnOrFormula(column= #JoinColumn( name="childId",referencedColumnName="childId",nullable=false))
})
private Child child;
public Long getSubChildId() {
return subChildId;
}
public void setSubChildId(Long subChildId) {
this.subChildId = subChildId;
}
public String getFff() {
return fff;
}
public void setFff(String fff) {
this.fff = fff;
}
public String getGgg() {
return ggg;
}
public void setGgg(String ggg) {
this.ggg = ggg;
}
public Integer getHhh() {
return hhh;
}
public void setHhh(Integer hhh) {
this.hhh = hhh;
}
public Child getChild() {
return child;
}
public void setChild(Child child) {
this.child = child;
}
}
Repository method used for persisting the list of Parent Entity
#Value("${spring.jpa.hibernate.jdbc.batch_size}")
private int batchSize;
public <T extends Parent> Collection<T> bulkSave(Collection<T> entities) {
final List<T> savedEntities = new ArrayList<T>(entities.size());
int i = 0;
for (T t : entities) {
savedEntities.add(persistOrMerge(t));
i++;
if (i % batchSize == 0) {
// Flush a batch of inserts and release memory.
entityManager.flush();
entityManager.clear();
}
}
return savedEntities;
}
private <T extends Parent> T persistOrMerge(T t) {
if (t.getTimeSlotId() == null) {
entityManager.persist(t);
return t;
} else {
return entityManager.merge(t);
}
}
application.yml
spring:
application:
name: sample-service
jpa:
database: MYSQL
show-sql: true
hibernate:
ddl-auto: update
dialect: org.hibernate.dialect.MySQL5Dialect
naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy
jdbc:
batch_size: 100
jackson:
date-format: dd/MM/yyyy
thymeleaf:
cache: false
spring.datasource.url : jdbc:mysql://${dbhost}/sample?createDatabaseIfNotExist=true
spring.datasource.username : root
spring.datasource.password : root
spring.datasource.driver-class-name : com.mysql.cj.jdbc.Driver
To enable batch insert you need the batch_size property which you have in your configuration.
Also since a jdbc batch can target one table only you need the spring.jpa.hibernate.order_inserts=true property to order the insert between parent and child or else the statement are unordered and you will see a partial batch (new batch anytime an insert in a different table is called)

EclipseLink Basic FetchType.LAZY configuration

I'm having some trouble getting an attribute on an entity to lazy load. I've scoured the EclipseLink documentation but can't figure out what I'm doing wrong.
Basically, I have a table with some columns, one of which is a file, the size of which can be very large. I'd like to have the file itself lazy load, so that when I load all the rows of the table I don't have to wait for the file to load into memory if it won't be used.
The setup:
EclipseLink 2.6.2
ReportHistoryFile:
#Entity
#Table(name = "REPORT_HISTORY_FILES")
#NamedQueries({
#NamedQuery(name = "ReportHistoryFile.findAll", query = "SELECT p FROM ReportHistoryFile p order by p.createDate DESC")})
public class ReportHistoryFile implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#SequenceGenerator(name = "SEQ_REPORTHISTORYFILE_GEN", sequenceName = "SEQ_REPORTHISTORYFILE", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_REPORTHISTORYFILE_GEN")
private Long fileId;
// note the basic lazy setting
#Basic(fetch = FetchType.LAZY)
#Column(name = "FILE_CONTENT", nullable = false)
private byte[] fileContent;
#Column(name = "FILE_NAME", nullable = false)
private String fileName;
private String contentType;
#Column(name = "FILE_SIZE")
private Long fileSize;
#Column(name = "CREATEDATE")
private Date createDate;
public ReportHistoryFile() {
}
public Long getFileId() {
return fileId;
}
public void setFileId(Long fileId) {
this.fileId = fileId;
}
public byte[] getFileContent() {
if (fileContent == null) {
return null;
}
return Arrays.copyOf(fileContent, fileContent.length);
}
public void setFileContent(byte[] fileContentIn) {
if (fileContentIn != null) {
this.fileContent = Arrays.copyOf(fileContentIn, fileContentIn.length);
}
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public Long getFileSize() {
return fileSize;
}
public void setFileSize(Long fileSize) {
this.fileSize = fileSize;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getCreateDate() {
return this.createDate;
}
}
But when I execute this code (em is the EntityManager):
List<ReportHistoryFile> list = null;
try {
list = (List<ReportHistoryFile>) em.createNamedQuery("ReportHistoryFile.findAll")
.getResultList();
} catch (javax.persistence.NoResultException e) {
log.info("No Report History File records found.");
} catch (Exception e) {
log.error(e.getMessage(), e);
}
I see this printed out to the console:
[EL Fine]: sql: 2017-01-25 10:35:44.223--ServerSession(1159663071)--Connection(39105078)--SELECT FILEID, CONTENTTYPE, CREATEDATE, FILE_CONTENT, FILE_NAME, FILE_SIZE FROM REPORT_HISTORY_FILES ORDER BY CREATEDATE DESC
Notice that FILE_CONTENT is still in the statement. What am I missing? I don't think I need anything special in my persistence.xml file for just the basic lazy load, but I could be wrong. Thanks in advance!
In order to enable lazy loading feature for properties and relations, your classes must be weaved by eclipseLink using
static weaving
dynamic weaving
How to do this you can read here, working example can be found here

Why JPA doesnt generate a join junction table in this case

I have two tables Students and Books , with a many to many relationship. The code of both are given below. Now when I try to run the code I get the error.
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'acme.book_stud' doesn't exist
Error Code: 1146
Call: INSERT INTO book_stud (idStudents, idBooks) VALUES (?, ?)
bind => [2 parameters bound]
It seems like JPA is trying to write to a juction table which does not exist (in this case it assumes a junction table books_students is already created so it doesnt create one.). It works if I create a books_students but I dont want to do that since its JPA responsibility to create it. Is there a way in which I could explicitly tell it to create one. ? (I am taking a wild guess here - but I guess when creating a persitance unit I specified "none" I think thats why it didnt create that table . Am I correct ? Anyways here are my Student and Books Classes
BOOKS CLASS
#Entity
#Table(name = "books")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Books.findAll", query = "SELECT b FROM Books b"),
#NamedQuery(name = "Books.findByIdBooks", query = "SELECT b FROM Books b WHERE b.idBooks = :idBooks"),
#NamedQuery(name = "Books.findByBookName", query = "SELECT b FROM Books b WHERE b.bookName = :bookName"),
#NamedQuery(name = "Books.findByBookType", query = "SELECT b FROM Books b WHERE b.bookType = :bookType")})
public class Books implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "idBooks")
private String idBooks;
#Size(max = 45)
#Column(name = "BookName")
private String bookName;
#Size(max = 45)
#Column(name = "BookType")
private String bookType;
/******************************************ADDED **********************/
#ManyToMany
#JoinTable(name = "book_stud",
joinColumns = { #JoinColumn(name = "idStudents") },
inverseJoinColumns = { #JoinColumn(name = "idBooks") })
/**************************************ENDED*****************************/
public Books() {
}
public Books(String idBooks) {
this.idBooks = idBooks;
}
public String getIdBooks() {
return idBooks;
}
public void setIdBooks(String idBooks) {
this.idBooks = idBooks;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getBookType() {
return bookType;
}
public void setBookType(String bookType) {
this.bookType = bookType;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idBooks != null ? idBooks.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 Books)) {
return false;
}
Books other = (Books) object;
if ((this.idBooks == null && other.idBooks != null) || (this.idBooks != null && !this.idBooks.equals(other.idBooks))) {
return false;
}
return true;
}
#Override
public String toString() {
return "domain.Books[ idBooks=" + idBooks + " ]";
}
}
STUDENT CLASS
#Entity
#Table(name = "students")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "StudentEnroll.findAll", query = "SELECT s FROM StudentEnroll s"),
#NamedQuery(name = "StudentEnroll.findByIdStudents", query = "SELECT s FROM StudentEnroll s WHERE s.idStudents = :idStudents"),
#NamedQuery(name = "StudentEnroll.findByName", query = "SELECT s FROM StudentEnroll s WHERE s.name = :name"),
#NamedQuery(name = "StudentEnroll.findByRoll", query = "SELECT s FROM StudentEnroll s WHERE s.roll = :roll"),
#NamedQuery(name = "StudentEnroll.findBySsn", query = "SELECT s FROM StudentEnroll s WHERE s.ssn = :ssn"),
#NamedQuery(name = "StudentEnroll.findByProgram", query = "SELECT s FROM StudentEnroll s WHERE s.program = :program")})
public class StudentEnroll implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 40)
#Column(name = "idStudents")
private String idStudents;
#Size(max = 45)
#Column(name = "Name")
private String name;
#Column(name = "Roll")
private Integer roll;
#Column(name = "SSN")
private Integer ssn;
#Size(max = 45)
#Column(name = "Program")
private String program;
#JoinColumn(name = "CustomerID", referencedColumnName = "UserID")
#ManyToOne
private Customer customerID;
//#OneToMany(mappedBy = "studentRoll")
#OneToMany(mappedBy = "studentRoll",cascade = CascadeType.REMOVE)//added REMOVE
private Collection<Subject> subjectCollection;
/**************************ADDED*****************************/
#ManyToMany
#JoinTable(name = "book_stud",
joinColumns = { #JoinColumn(name = "idBooks") },
inverseJoinColumns = { #JoinColumn(name = "idStudents") })
/**********************************END**********************/
public StudentEnroll() {
}
public StudentEnroll(String idStudents) {
this.idStudents = idStudents;
}
public String getIdStudents() {
return idStudents;
}
public void setIdStudents(String idStudents) {
this.idStudents = idStudents;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getRoll() {
return roll;
}
public void setRoll(Integer roll) {
this.roll = roll;
}
public Integer getSsn() {
return ssn;
}
public void setSsn(Integer ssn) {
this.ssn = ssn;
}
public String getProgram() {
return program;
}
public void setProgram(String program) {
this.program = program;
}
public Customer getCustomerID() {
return customerID;
}
public void setCustomerID(Customer customerID) {
this.customerID = customerID;
}
#XmlTransient
public Collection<Subject> getSubjectCollection() {
return subjectCollection;
}
public void setSubjectCollection(Collection<Subject> subjectCollection) {
this.subjectCollection = subjectCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idStudents != null ? idStudents.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 StudentEnroll)) {
return false;
}
StudentEnroll other = (StudentEnroll) object;
if ((this.idStudents == null && other.idStudents != null) || (this.idStudents != null && !this.idStudents.equals(other.idStudents))) {
return false;
}
return true;
}
#Override
public String toString() {
return "domain.StudentEnroll[ idStudents=" + idStudents + " ]";
}
}