I use Spring data jpa and I have two Entities that have inheritance relationship.
Here is the parent.
#Entity
#Inheritance(strategy=InheritanceType.JOINED)
#Table(name = "creditcardinfo")
#DiscriminatorColumn
public class CreditCardInfo implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="credit_card_info_id")
private int creditCardInfoId;
And here is the child
#Entity
#DiscriminatorValue("tappay")
#Table(name = "tappaycardinfo")
#PrimaryKeyJoinColumn(name = "credit_card_info_id",referencedColumnName = "credit_card_info_id")
public class TappayCardInfo extends CreditCardInfo implements Serializable{
private static final long serialVersionUID = 1L;
#Column(name = "card_token")
private String cardToken;
#Column(name = "card_key")
private String cardKey;
And I use JpaRepository to CRUD. Here's my repository.
public interface TappayCardInfoDAO extends JpaRepository<TappayCardInfo, Integer>
I always got an Exception when I saved my TappayCardInfo.
#Inject private TappayCardInfoDAO tappayCardInfoDAO;
...
tappayCardInfoDAO.save(cardInfo);
Here's error message.
Caused by: java.lang.IllegalArgumentException: The entity must have one and only one property with id annotation, class name: base.model.TappayCardInfo
Related
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 have one Parent class with ID field, and two Child classes. I have applied TABLE PER CLASS inheritance.
Some Rows in these two tables have the same identifiers. (The same Id)
When findAll() of the JpaRepository is called I have org.hibernate.PropertyAccessException
What I can to do to resolve the conflict? I can not to change IDs in these tables, because they have a lot of dependencies and foreign key constraints.
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Parent implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#TableGenerator(name = "content_id_generator",
table = "generic_sequences",
pkColumnName = "sequence_name",
valueColumnName = "sequence_value",
pkColumnValue= "content_seq",
allocationSize = 20)
#GeneratedValue(strategy = GenerationType.TABLE, generator = "content_id_generator")
#Column(updatable = false)
private Long id;
#Column(length = 250, nullable = false)
#NotNull
#Size(min = 1, max = 250)
private String title;
...
There are tho child classes Child1 and Child2 extends Parent.
There is another inheritance that dependent from Content.
#Entity
#Table(name = "text_id_changed")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "type")
public abstract class DependentCalss implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(updatable = false)
private Long id;
...
DependentCalss has two child classes DependentCalssChild1 and DependentCalssChild2.
#Entity
#DiscriminatorValue("DependentCalssChild1")
public class DependentCalssChild1 extends DependentCalss {
private static final long serialVersionUID = 1L;
#ManyToOne
#JoinColumn(name = "child_1_id")
private Child1 child1;
...
AND
#Entity
#DiscriminatorValue("DependentCalssChild2")
public class DependentCalssChild2 extends DependentCalss {
private static final long serialVersionUID = 1L;
#ManyToOne
#JoinColumn(name = "child_2_id")
private Child2 child2;
...
And jpaRepository
#Repository
public interface DependentCalssRepository extends JpaRepository<DependentCalss, Long> {
}
When I call findAll() of DependentCalssRepository I catch org.hibernate.PropertyAccessException that field can not be set etc.
It happens when Child1 and Child2 have the same ID in separate tables.
What can I do to resolve it? I can not change id in tables because of great number dependencies and constraints. Thanks!
Here is how the entity class looks like
#Entity
public class IndustryCode {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String industryName;
#OneToMany(mappedBy="industryCode")
private Set<CarrierCodes> industryCodes;
#Entity
public class TechCode {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String techName;
#OneToMany(mappedBy="techCode")
private Set<CarrierCodes> techCodes;
#Entity
public class CarrierCodes {
#EmbeddedId
private CarrierCodesId id = new CarrierCodesId();
#ManyToOne
#MapsId("techCodeId")
private TechCode techCode;
#ManyToOne
#MapsId("industryCodeId")
private IndustryCode industryCode;
#SuppressWarnings("serial")
#Embeddable
public class CarrierCodesId implements Serializable {
private Long industryCodeId;
private Long techCodeId;
#Entity
public class Register {
#Id
private Long mobileNumber;
#ManyToOne
// optional but nice to have consistent names
#JoinColumns({
#JoinColumn(name="industryCode_id", referencedColumnName="industryCode_id"),
#JoinColumn(name="techCode_id", referencedColumnName="techCode_id")
)
private CarrierCodes carrierCodes;
}
public class RegisterRepository extends JPARepository<Register,mobileNumber>{
}
My question is if I run findAll on Register table will I get the data for other related tables as well?
I mean using findAll(), will I get a List from which I can take Register obj and use .getCarrierCode().getIndustryCode().getIndustryName() to get industry name corresponding to carrierCode value in Register table
I have a Spring JPA project with 3 entities: Author, Book and Category.
I want to use Hibernate Search for indexes.
Author class is #Indexed; Book class contains a Category field annotated with #ContainedIn; Category is a very simple class.
CLASS Author
#Entity
#Table
#Indexed
public class Author extends ConcreteEntity {
private static final long serialVersionUID = 1L;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#IndexedEmbedded
private List<Book> books = new ArrayList<>();
}
CLASS Book
#Entity
#Table
public class Book extends ConcreteEntity {
private static final long serialVersionUID = 1L;
#ContainedIn
private Category category;
}
CLASS Category
#Entity
#Table
public class Category extends ConceptEntity {
private static final long serialVersionUID = 1L;
}
CLASS ConcreteEntity and ConceptEntity are similars:
#MappedSuperclass
public abstract class ConcreteEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String name;
#Column
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String value;
}
#MappedSuperclass
public abstract class ConceptEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String name;
#Column
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String value;
}
I've got this exception while saving a resource using Hibernate Search.
org.hibernate.search.exception.SearchException: Unable to perform work. Entity Class is not #Indexed nor hosts #ContainedIn: class test.hibernate.search.Category
I don't understand how to solve this issue.
Thanks
Book is not configured correctly. You tell Hibernate Search that Book is included in the Category index (via your #ContainedIn annotation on the category field) but your Category entity is neither marked with #Indexed nor linked to another index via #ContainedIn.
Hibernate Search is just telling you that your configuration doesn't make much sense.
Considering your model, I'm pretty sure you wanted to mark category with #IndexedEmbedded instead.
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.