Inheritance in JPA not working - java

I have a parent class:
#MappedSuperclass
public class BaseText implements Serializable {
#Column(name = "LOCALE_CODE", nullable = false)
private String localeCode;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#Index
#Column(name = "LOCALIZED_TEXT_ID", nullable = false)
#ForeignKey
private LocalizedText localizedText;
//getters and setters
}
And one of the sub classes:
#Entity
#Table(name = "ASSESSMENT_TEXT")
#AttributeOverride(name = "localeCode", column = #Column(name = "LOCALE_CODE"))
#AssociationOverride(name = "localizedText", joinColumns = #JoinColumn(name = "LOCALIZED_TEXT_ID"))
public class AssessmentText extends BaseText {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID")
private Long id;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#Index
#Column(name = "ASSESSMENT_ID", nullable = false)
#ForeignKey
private Assessment assessment;
//Getters and setters.
}
When I am trying to persist an object I get the following error:
org.apache.openjpa.persistence.ArgumentException: Superclass field "java.lang.Object.localizedText" is mapped in the metadata for subclass "com.my.com.AssessmentText", but is not a persistent field.
What is causing this and how to solve it?
I am using embedded derby database in JUnit and the JPA implementation is OpenJPA.

I am not sure that it is the solution, but I miss an #Inheritance annotation from AssessmentText:
#Entity
#Table(name = "ASSESSMENT_TEXT")
#Inheritance(strategy=InheritanceType.JOINED)
#AttributeOverride(name = "localeCode", column = #Column(name = "LOCALE_CODE"))
#AssociationOverride(name = "localizedText",
joinColumns = #JoinColumn(name = "LOCALIZED_TEXT_ID"))
public class AssessmentText extends BaseText {

I had the same issue, and solved it by adding the MappedSuperClass to the persistence.xml.
I know this is also in the comments somewhere, but the useful one was hidden and I think this should be an answer, not a comment to the question.

Related

Hibernate delete all objects associations that reference the object unidirectional using ManyToOne

I have a ModuleData object and a Setting object that references this ModuleData object, but the ModuleData object does not have any reference to the Setting object. Does Hibernate automatically delete the objects that reference ModuleData and if not, how do I accomplish that Hibernate does this.
ModuleData.java
#Entity
#Table(name = "modules")
public class ModuleData {
#Id
#GeneratedValue
#Column(name = "id", updatable = false, nullable = false)
private long id;
#Column(name = "name")
private String name;
#Column(name = "version")
private String version;
}
Setting.java
#Entity
#Table(name = "settings", uniqueConstraints = #UniqueConstraint(columnNames = {"settingKey"}))
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Setting {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "settingKey", nullable = false)
private String key;
#Column
private String value;
#ManyToOne
#JoinColumn(name = "moduleId", nullable = false)
private ModuleData module;
I will delete by session.delete(moduleData).
You can add the other side of the relation (i.e. add the Setting property to the ModuleData class), and then use Java Persistence 'cascade types' to accomplish this. Specifically the CascadeType.REMOVE will give you the desired behavior. From this great tutorial, your ModuleData class would reference its Setting child similar to this:
#OneToMany(cascade = CascadeType.ALL, mappedBy = "post", orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();
so it would look something like:
#OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true, ...)
private List<Setting> settings;
Another great tutorial on cascade types:
https://www.baeldung.com/jpa-cascade-types

HIbernate ignore fetching data from OnetoMany field

I would like to ignore #OnetoMany field in my entity. fetch data need to get actual fields but don't want to fire query to dependent table. But deleting data from parent table needs deletion from dependent table
I have tried #Transient that ignores but the delete is also being ignored. Is there any other option to tell JPA not to fetch data from childs table when i call the parent entity?
#Entity
Table(name = "User")
public class UserEntity implements Serializable {
#Id
#Column(name = "id")
private int id;
#Column(name = "SERIAL", unique = true, nullable = false)
private String serial;
#OneToMany(mappedBy = "serialBySerialId", cascade = CascadeType.ALL)
private Set<UserActionEntity> userActionsById;
}
#Table(name = "user_action")
public class UserActionEntity implements Serializable {
#Id
#Column(name = "id")
private int id;
#Column(name = "action")
private String action;
#ManyToOne
#JoinColumn(name = "USER_ID", referencedColumnName = "ID", nullable = false)
private UserEntity userByUserId;
If you don't want to fire query to dependent table, you can use (fetch = FetchType.LAZY) on UserActionEntity property.
#OneToMany(mappedBy = "serialBySerialId", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserActionEntity> userActionsById;

JPA: OneToMany relationship with multiple mappedBy attributes

I'm having a problem to map a relationship between instances of one single entity. Let me give you the JPA entities first.
Article entity
#Entity
#Table(name = "article")
public class Article {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "article", orphanRemoval = true)
private Collection<Keyword> keywords;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "article1", orphanRemoval = true)
private Collection<RelatedArticles> relatedArticles;
#Column(name = "content", nullable = false)
#Lob
private String content;
...
}
RelatedArticle entity
#Entity
#Table(name = "related_articles")
public class RelatedArticles {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#JoinColumn(name = "article1_id")
#ManyToOne(optional = false)
private Article article1;
#JoinColumn(name = "article2_id")
#ManyToOne(optional = false)
private Article article2;
private Float weightedJaccardIndex;
...
}
Further explanation
An article can be related to other articles which is realized by the RelatedArticle entity. The article can be referenced by article1 or article2. That means the collection relatedArticles in Article should contain all instances of RelatedArticle where the ID either matches article1 or article2.
Question
How can I map a single collection of RelatedArticles in my Article entity where the origin Article is either article1 or article2?
Alternative solutions are welcome!

Hiibernate: #OrderColumn in #OneToMany causes an UPDATE after INSERT

I have the following POJOs for my db schema.
#Entity
#Table(name = "Quotes")
public class QuoteRequest
{
public QuoteRequest(){}
#Id
#Column(name = "quote_request_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long QuoteRequestId;
#OneToMany(mappedBy = "quoteRequest", cascade = CascadeType.ALL)
#OrderColumn(name = "accidents_id")
private Accidents[] accidents;
// Getters and setters
}
#Entity
#Table(name = "Accidents")
public class Accidents
{
public Accidents()
{
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "accidents_id")
private long AccidentId;
#Column(name = "amount", nullable = false)
private Float amount;
#ManyToOne(optional = false, cascade = CascadeType.ALL)
#JoinColumn(name = "quote_request_id", nullable = false)
private QuoteRequest quoteRequest;
// Getters and setters
}
Because I'm using an array to store Accidents[] Hibernate is requiring me to add #OrderColumn. Adding this causes an update to be generated after insert that zeros out my accidents_id. The only way I found around that is to change Accidents[] to Set.
How can I keep Accidentsas an array and not have Hibernate force this 2nd update after the insert?

jpa mapping two properties

I need CompanyUser.companyRolCompanyUsers property with OneToMany relation, completed in each query.
JPA company_usr entity:
#Entity
#Table(name = "company_usr")
public class CompanyUser extends BaseModel implements Serializable {
#Id
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(nullable = false)
private Company company;
#Id
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "usr_id", nullable = false)
private User user;
#Column(nullable = false)
private Boolean external;
#OneToMany(fetch = FetchType.EAGER)
private List<CompanyRolCompanyUser> companyRolCompanyUsers;
....
JPA companyRol_companyUsr entity:
#Entity
#Table(name = "companyRol_companyUsr")
public class CompanyRolCompanyUser extends BaseModel implements Serializable {
#Id
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumns({
#JoinColumn(name="companyuser_company_id", referencedColumnName="company_id"),
#JoinColumn(name="companyuser_usr_id", referencedColumnName="usr_id")
})
private CompanyUser companyUser;
#Id
#ManyToOne(fetch = FetchType.EAGER)
private CompanyRol companyRol;
....
How to set mappedBy in companyRolCompanyUsers property correctly?
If i get what you want to achieve i think you need something like :
#OneToMany(fetch = FetchType.EAGER, mappedBy="companyUser")
private List<CompanyRolCompanyUser> companyRolCompanyUsers;
You can have two properties for the same column like this :
#JoinColumn(name = "CGRADO_CODIGO", referencedColumnName = "CGRADO_CODIGO")
#ManyToOne
#NotFound(action=NotFoundAction.IGNORE)
private SipreGrado sipreGrado;
#Column(name = "CGRADO_CODIGO",insertable=false,updatable=false)
private String sipreGradoCodigo;
Remember if you have sometimes the entity NULL you can skip it with that annotation
#NotFound(action=NotFoundAction.IGNORE)
Also,Remember to set
insertable=false,updatable=false
for the one that you dont want to include in the insert/update queries.

Categories