Hello I hope you can help me, I have a problem with the inserts in hibernate.
First I have a Person class
#Entity
#Table(name = "persons")
#Inheritance(strategy = InheritanceType.JOINED)
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "id_card", columnDefinition = "VARCHAR(13)")
private String idCard;
#Column(name = "name", columnDefinition = "VARCHAR(50) NOT NULL")
private String name;
#Column(name = "last_name", columnDefinition = "VARCHAR(50) NOT NULL")
private String lastName;
}
And I have two classes plus one provider.
#Entity
#Table(name = "providers")
public class Provider extends Person implements Serializable {
private static final long serialVersionUID = 1L;
public Provider() {
// TODO Auto-generated constructor stub
}
}
Customer
#Entity
#Table(name = "customers")
public class Customer extends Person implements Serializable {
private static final long serialVersionUID = 1L;
public Customer() {
// TODO Auto-generated constructor stub
}
}
What happens is that I insert a provider and there is no problem, just like when inserting a client there is no problem, what happens is that when I already insert a person as a client I can no longer insert them as a supplier I get that the key.
What happens is that a person can be a customer and a supplier or an employee at the same time.
ER Diagram
Related
What's the correct way to create bidirectional 1to1 mapping using Embeddable annotation? This one throws error
"EmpId has no persistent id property: Emp.id"
#Entity
public class Per implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "per_id")
private Long id;
#OneToOne
#JoinColumn(name = "per_id", referencedColumnName = "emp_id")
private Emp emp;
}
#Embeddable
public class EmpId implements Serializable {
private static final long serialVersionUID = 1L;
#OneToOne(mappedBy = "emp")
private Per per;
}
#Entity
public class Emp implements Serializable {
#EmbeddedId
private EmpId id;
}
I'd like to operate entities like
per.getEmp();
emp.getId().getPer();
Good morning, how can I add fields in my audit table?
I need to audit some tables, but I need to get the user who did the operation. My entity who will be audited is:
#Entity
#Table(name ="TableName")
#Audited
#AuditTable("TableNameAuditedLog")
public class MyEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "myId")
private Long id;
#Column(name = "myName")
private String name;
}
Looking the docs, I saw an example a custom class to be my audit and a listener, so I made like this:
#Data
#RevisionEntity(AuditListener.class)
#MappedSuperclass
public class Audit {
#Id
#GeneratedValue
#RevisionNumber
private Long id;
#RevisionTimestamp
private Long timestamp;
#Column(name = "user")
private String user;
}
public class AuditListener implements RevisionListener {
#Override
public void newRevision(Object revisionEntity) {
Audit audit = (Audit) revisionEntity;
audit.setUsuario("user");
}
}
I've tried to extends my Audit class in my Entity class, but I'd trouble with JPA, the trouble is:
Caused by: org.hibernate.MappingException: Unable to find column with logical name: myId in org.hibernate.mapping.Table(TableNameAuditedLog) and its related supertables and secondary tables
How can I do this?
Thank you all.
Remove the MappedSuperClass from your Audit class. You could also have Audit extend DefaultRevisionEntity. All you would have in Audit class is your custom field.
#Column(name = "user")
private String user;
A custom audit revision entity:
#Entity
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#RevisionEntity(UserRevisionListener.class)
public class AuditRevisionEntity extends DefaultTrackingModifiedEntitiesRevisionEntity {
private static final long serialVersionUID = 1L;
private Long userId;
#Column(length = 100, nullable = false)
private String initiator;
}
And revision listener
public class UserRevisionListener implements RevisionListener {
private static final String SYSTEM_USER = "System";
private transient final SecurityUtils securityUtils;
public UserRevisionListener(final SecurityUtils securityUtils) {
this.securityUtils = securityUtils;
}
#Override
public void newRevision(Object revisionEntity) {
final AuditRevisionEntity are = (AuditRevisionEntity) revisionEntity;
securityUtils.getPrincipal().ifPresentOrElse((appPrincipal) -> {
are.setUserId(appPrincipal.getUserId());
are.setInitiator(appPrincipal.getDisplayName());
}, () -> are.setInitiator(SYSTEM_USER));
}
}
In my case I am getting the current principal(I am using a custom principal that has the extra fields) using a SecurityUtils helper and setting the AuditRevisionEntity as needed. Some changes are made by Quartz jobs so there is no principal in which case only the initiator is set.
I am new to JPA and doing a small sample to learn about it.
But I got one problem below, please help me out, and please explain why:
I have class Customer.java, which is mapped to table customer in db:
#Entity
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "id_customer")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
// accountNumber field maps with accountNumber column in Account table
#Column(name = "loginId", unique = true)
private String loginId;
#Column(name = "password")
private String password;
#Column(name = "firstName")
private String firstName;
#Column(name = "lastName")
private String lastName;
#Column(name = "address")
private String address;
#Column(name = "email")
private String email;
#Column(name = "phone")
private String phone;
#OneToMany(mappedBy="customer")
private List<Account> accountList;
#OneToMany(mappedBy="customer")
private List<Card> cardList;
// getters and setters goes here
}
The above class has two lists, accountList and cardList, their generic Class (Card and Account) extends BaseInfo using Single table Inheritance.
Here is my BaseInfo.java:
#Entity
#Table(name = "account")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
public class BaseInfo implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "number")
private String number;
#Column(name = "availableNumber")
private Long availableNumber;
//getter and setter here
}
Class Card.java:
#Entity
#Table(name = "account")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorValue(value = "C")
public class Card extends BaseInfo implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "cardType")
private String cardType;
#ManyToOne
#JoinColumn(name = "id_customer")
private Customer customer;
//getter and setter
}
And class Account.java:
#Entity
#Table(name = "account")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorValue(value = "A")
public class Account extends BaseInfo implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "accountName")
private String accountName;
#Column(name = "accountType")
private String accountType;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "dt_created")
private Date createdDate;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "dt_lst_updt")
private Date lastUpdatedDate;
#ManyToOne
#JoinColumn(name = "id_customer")
private Customer customer;
//getter, setter
}
Then, I do a query that query customer from database with loginid and password, like this:
entityTransaction.begin();
TypedQuery<Customer> query = entityManager.createQuery(
"SELECT c FROM " + Customer.class.getName()
+ " c Where c.loginId= :loginId", Customer.class);
query.setParameter("loginId", loginId);
res = query.getSingleResult();
entityTransaction.commit();
The code run with no error, but the result is somethings strange to me: When I debug (or print out the result to jsp), accountList or cardList contains all Account of that customer, just like they don't care about the 'discriminator' column.
I have 2 questions:
How can I archive the goal that listCard contains only Card (discrimination = c) and listAccount contains only Account (discriminator = a) ?
Is there an alternative way to query listCard or listAccount without query the customer first (like I use) ??
Thank in advance! :D
I'm not sure if it's a JPA restriction or a Hibernate-specific restriction, but you may not use the same column to map two different associations.
You should use something like car_customer_id to map the association between customer and cards, and account_customer_id to map the association between customer and accounts.
I am having two tables Parent and Child. The query I want to use in Hibernate Criteria
SELECT tcr.*
FROM case_reminders tcr
INNER JOIN case_reminder_opr tco ON tcr.case_id = tco.case_id
WHERE tcr.case_status = 'OPN'
AND tco.operator_id = 111;
I have written the criteria as
Criteria ctr = getSession().createCriteria(CaseReminderOpr.class).add(Restrictions.eq("pk.oprOperatorId", operatorId));
ctr.createCriteria("pk.crmCaseId", "CR", Criteria.INNER_JOIN).add(Restrictions.eq("CR.caseStatus", STATUS.OPEN.getValue()));
List<CaseReminderOpr> oprList = ctr.list();
tried with createAlias as well but I am getting error as
ORA-00904: "CR1_"."CASE_STATUS": invalid identifier
Classes of CaseReminders(Parent) and CaseReminderOpr(Child) as follows.
#Entity
#Table(name = "CASE_REMINDERS")
public class CaseReminders implements Serializable {
#Id
#Column(name = "CASE_ID")
private Long caseId;
#Column(name = "CASE_STATUS")
private String caseStatus;
}
#Entity
#Table(name="CASE_REMINDER_OPR")
public class CaseReminderOpr implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private CaseReminderOprPK pk;
}
#Embeddable
public class CaseReminderOprPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
#ManyToOne
#JoinColumn(name = "CASE_ID")
private CaseReminders crmCaseId;
#Column(name="OPERATOR_ID")
private Long operatorId;
}
Please help me with the inner_join query, appreciate your help again.
The change would be as below then it works. I have realized this later.
Make the Joincolumn as insertable=false,updatable=false in main entity class.
#Entity
#Table(name="CASE_REMINDER_OPR")
public class CaseReminderOpr implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private CaseReminderOprPK pk;
#ManyToOne
#JoinColumn(name = "CASE_ID", insertable=false, updatable=false)
private CaseReminders caseRem;
}
Now the query should work as expected.
Criteria ctr = getSession().createCriteria(CaseReminderOpr.class, "CRO").add(Restrictions.eq("pk.oprOperatorId", operatorId));
ctr.createCriteria("CRO.caseRem", "CR", Criteria.INNER_JOIN).add(Restrictions.eq("CR.caseStatus", STATUS.OPEN.getValue()));
List<CaseReminderOpr> oprList = ctr.list();
Hopefully I am clear in explaining.
I have the following
#Entity
#Table(name = "PROJECTS")
public class Project implements Serializable {
#Id
private Integer SlNo;
#Id
private Long projectNo;
private Date projectDate;
}
and in DAO class
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> countQ = cb.createQuery(Long.class);
Root<Project> empCount = countQ.from(Project.class);
countQ.select(cb.count(empCount));
TypedQuery<Long> countquery = entityManager.createQuery(countQ);// error in this line
I am getting exception java.lang.IllegalStateException: No supertype found in the above line. How can I resolve or workaround this issue? Looks like there is a bug, are there any solution to this?
I am using Hibernate 4.1.0.Final
I have resolved the issue by using #EmbeddedId in Entity class and #Embeddable in Primary Key class.
#Entity
#Table(name = "PROJECTS")
public class Project {
#Column(name = "SL_NO" , insertable = false, updatable = false)
private Integer SlNo;
#Column(name = "PROJECT_NO" , insertable = false, updatable = false)
private Long projectNo;
private Date projectDate;
#EmbeddedId
ProjectPK projectPK;
and Primary Key class
#Embeddable
public class ProjectPK implements Serializable {
#Column(name = "SL_NO")
private Integer SlNo;
#Column(name = "PROJECT_NO")
private Long projectNo;
//with hashCode and equals implementation
for the case Using #EmbeddedId, here is my solution. This code I have written in one class itself, in Entity class.
Class MyEntity - It is my actual Entity class for my table. "OtherFields" are those fields which are not part of primary key.
Class MyEntityPrimaryKeys - It is the class made for my composite key which makes a primary key for my "MyEntity" class. Here ROLLNO and AGE together makes a primary key.
MyEntity.java
#Entity
#Table(name = "myTable")
public class MyEntity extends GenericPersistableEntity implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
MyEntityPrimaryKeys id;//Composite Primary key
//Composite fields can be declared here for getter and setters
#Column(name = "ROLLNO")
private Long RollNo;
//Composite fields can be declared here for getter and setters
#Column(name = "AGE")
private Long age;
#Column(name = "OtherFields"
private Long OtherFields;
//getter and setters comes here
}
#Embeddable
class MyEntityPrimaryKeys implements Serializable{
private static final long serialVersionUID = 1L;
#Column(name = "ROLLNO")
Long RollNo;
#Column(name = "AGE")
Long age;
#Override
public int hashCode() {
HashCodeBuilder hcb = new HashCodeBuilder();
hcb.append(RollNo);
hcb.append(age);
return hcb.toHashCode();
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof MyEntityPrimaryKeys)) {
return false;
}
MyEntityPrimaryKeys that = (MyEntityPrimaryKeys) obj;
EqualsBuilder eb = new EqualsBuilder();
eb.append(RollNo, that.RollNo);
eb.append(age, that.age);
eb.append(tonMonth, that.tonMonth);
eb.append(tonYear, that.tonYear);
return eb.isEquals();
}
}