How to configure mapping? I want to table "Remittance" were two columns referring to the table "Expense"
Remittance
#Entity
#Table(name = "REMITTANCE")
public class Remittance implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "REMITTANCE_ID")
private Long id;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "remittances", cascade = CascadeType.ALL)
private Expense from;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "remittances", cascade = CascadeType.ALL)
private Expense to;
}
Expense
#Entity
#Table(name = "EXPENSE")
public class Expense implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "EXPENSE_ID")
private Long id;
#ManyToOne(optional = false)
#JoinColumn(name = "REMITTANCE_ID")
private Remittance remittances;
}
I made a mistake. I have corrected
Remittance
#Entity
#Table(name = "REMITTANCE")
public class Remittance implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "REMITTANCE_ID")
private Long id;
#ManyToOne(optional = false)
#JoinColumn(name = "EXPENSE_ID")
private Expense from;
#ManyToOne(optional = false)
#JoinColumn(name = "EXPENSE_ID")
private Expense to;
}
Expense
#Entity
#Table(name = "EXPENSE")
public class Expense implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "EXPENSE_ID")
private Long id;
}
but now out
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: ru.make.alex.web.model.revenue.Remittance column: EXPENSE_ID (should be mapped with insert="false" update="false")
Related
I have a tree-like data structure in my application.
For example, main entity is DraftDoc, it has a child entity DraftEffect. And DraftEffect has its own child entity DraftOffenderCategory.
What is the best strategy for persisting the data to the database?
To collect the whole tree on the front-end side to one big JSON and persist everything at once?
Or to take DraftDoc data (not including related entities) and persist, then take DraftEffect data and persist and so on?
#Entity
#Table(name = "TN_DRAFT_DOCS")
public class DraftDoc implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "DRAFTDOC_SEQ")
#SequenceGenerator(name = "DRAFTDOC_SEQ", sequenceName = "NT_DRAFT_DOC_SEQ")
#Column
private Long id;
#Column(name = "ARTICLE_ID")
private Long articleId;
#Column(name = "ARTICLE_VERSION")
private Long articleVersion;
#OneToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY)
#JoinTable(name = "TN_DRAFT_R_DOC_EFF", joinColumns = { #JoinColumn(name = "doc_id", referencedColumnName = "id") }, inverseJoinColumns = { #JoinColumn(name = "eff_id", referencedColumnName = "id") })
private List<DraftEffect> effects;
...
}
#Entity
#Table(name = "TN_DRAFT_EFFECT")
public class DraftEffect {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "DRAFT_EFFECT_SEQ")
#SequenceGenerator(name = "DRAFT_EFFECT_SEQ", sequenceName = "NT_DRAFT_EFFECT_SEQ")
#Column
private Long id;
#Column(name = "ARTICLE_ID")
private Long articleId;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "effect")
private List<DraftAffection> affections;
...
}
#Entity
#Table(name = "TN_DRAFT_AFFECTION")
public class DraftAffection implements Serializable {
private static final long serialVersionUID = 3048761786638684368L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "DRAFTAFFECTION_SEQ")
#SequenceGenerator(name = "DRAFTAFFECTION_SEQ", sequenceName = "NT_DRAFT_AFFECTION_SEQ")
#Column
private Long id;
#Column(name = "ARTICLE_ID")
private Long articleId;
...
}
See code below for my 2 entity classes - when I call the findAll() method from my OrigRepository class, it joins these two tables using both primary keys. I want the join to be between the primary key of the Orig table and the foreign key entry in the MsgResponse table ("OrigID") - any sugggestions?
Orig Entity
#Entity
#Table(name = "originator")
public class Orig {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "OrigID")
private int OrigID;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "OrigID")
private MsgResponse responseInfo;
}
MsgResponse Entity
#Entity
#Table(name = "message_response")
public class MsgResponse {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private int responseId;
#Column(name = "OrigID")
private int OrigId;
#OneToOne(mappedBy="responseInfo")
private Orig OrigInfo;
}
I suggest you to see the jpa documentation
here.
Example 1 should be your case
Try to swap relation ownership, that is:
#Entity
#Table(name = "originator")
public class Orig {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "OrigID")
private int OrigID;
#OneToOne(mappedBy="origInfo")
private MsgResponse responseInfo;
}
#Entity
#Table(name = "message_response")
public class MsgResponse {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private int responseId;
// #Column(name = "OrigID")
// private int origId;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "OrigID")
private Orig origInfo;
}
Note that the #JoinColum annotation is in now in the MsgResponse entity. This is because in a #OneToOne the join column refers to the source entity (see here).
Hope this could help.
How select records without parent with Hibernate using Criteria API?
Here is my Java code for select with parents
getSessionFactory().getCurrentSession().createCriteria(Category.class).add(
Restrictions.eq("parent", new Category(parentId))).list();
Category Java code
#Entity
#Table(name = "CATEGORY")
public class Category implements NamedModel{
#Id
#Column(name = "CATEGORY_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#OneToOne(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
#JoinTable(name = "CATEGORY_RELATIONS",
joinColumns = {
#JoinColumn(name = "CATEGORY_RELATIONS_CATEGORY_ID", referencedColumnName = "CATEGORY_ID")},
inverseJoinColumns = {
#JoinColumn(name = "CATEGORY_RELATIONS_PARENT_ID", referencedColumnName = "CATEGORY_ID")})
private Category parent;
#OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, mappedBy = "parent")
private List<Category> children;//...
}
CategoryRelations Java code
#Entity
#Table(name = "CATEGORY_RELATIONS")
#IdClass(CategoryRelations.CategoryRelationsPrimaryKey.class)
public class CategoryRelations implements Serializable {
#Id
#Column(name = "CATEGORY_RELATIONS_CATEGORY_ID")
private long categoryId;
#Id
#Column(name = "CATEGORY_RELATIONS_PARENT_ID")
private long parentId;
#Entity
#IdClass(CategoryRelationsPrimaryKey.class)
public static class CategoryRelationsPrimaryKey implements Serializable {
private long categoryId;
private long parentId;
}
}
You can use Restriction#isNull(propertyName) function for your requirements.
Restrictions.isNull("parent")
I have a little JPA question.
Assume you have such tables: (structure is fixed)
PERSON
--
ID,
DEPARTMENT_ID
...
SPECIALWORKER
------
ID, PERSON_ID, SPECIALDEPARTMENT_ID
...
DEPARTMENT
-------
ID,
...
SPECIALDEPARTMENT
-------
ID,
...
In Java I would build it with a simple hierarchy: SpecialWorker extends Person and SpecialDepartment extends Department. We will have "simple" Persons as well as "simple" Departments.
In JPA I try to build that scenario with a JOINED_Table inheritance, but I can't get it working. Any ideas?
edit
the coding, i hope i missed nothing.
I got a integrity exception when i try to insert a specialworker.
When i insert a specialworker jpa has to set the fk to departement (baseclass person) as well as the fk to the special departement (from the concrete current class)
#Entity
#Table(name = "DEPARTEMENT")
#Access(AccessType.FIELD)
#Inheritance(strategy = InheritanceType.JOINED)
public class Departement
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID")
private Integer id;
...
}
#Entity
#Table(name = "SPECIALDEPARTEMENT")
#Access(AccessType.FIELD)
#PrimaryKeyJoinColumn(name = "ID_DEPARTEMENT", referencedColumnName = "ID")
public class SpecialDepartement
extends Departement
implements Serializable
{
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", updatable = false, insertable = false)
private Integer id01;
#OneToMany(mappedBy = "specialDepartement", cascade = CascadeType.ALL, orphanRemoval = true)
private List<SpecialWorker> workers;
...
}
#Entity
#Table(name = "PERSON")
#Access(AccessType.FIELD)
#Inheritance(strategy = InheritanceType.JOINED)
public class Person
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID")
#Max(19)
private Long id;
#ManyToOne
#JoinColumn(name = "ID_DEPARTEMENT", referencedColumnName = "ID", nullable = false)
private Departement departement;
...
}
#Entity
#Table(name = "SWORKER")
#Access(AccessType.FIELD)
#PrimaryKeyJoinColumn(name = "ID_PERSON", referencedColumnName = "ID")
public class SpecialWorker
extends Person
{
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", updatable = false, insertable = false)
private Integer id01;
#ManyToOne
#JoinColumn(name = "ID_SPECIALDEPARTEMENT", referencedColumnName = "ID", nullable = false)
private SpecialDepartement specialdepartement;
I have some big problems with making a proper mapping for delivered diagram. It looks like this:
Now, so far I did this, hopefully its ok (ommited getters/setters). You'll notice that USERS has DOMAIN_ID, ignore it as it is not full diagram.
FunctionalityGroup
#Entity
#Table(name = "FUNCTIONALITY_GROUP")
public class FunctionalityGroup implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "FUNCTIONALITY_GROUP_ID")
private Long functionalityGroupId;
#Column(name = "FUNCTIONALITY_GROUP_NM")
private String functionalityGroupName;
#Column(name = "FUNCTIONALITY_GROUP_DESC")
private String functionalityGroupDesc;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "funcionalityGroupId")
private List<Functionality> functionalityList;
}
Functionality
#Entity
#Table(name = "FUNCTIONALITY")
public class Functionality implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "FUNCTIONALITY_ID")
private Long functionalityId;
#Column(name = "FUNCTIONALITY_NM")
private String functionalityGroupName;
#Column(name = "FUNCTIONALITY_DESC")
private String functionalityGroupDesc;
#Column(name = "FUNCTIONALITY_GROUP_ID")
private Long funcionalityGroupId;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "ROLE_FUNCTIONALITY",
joinColumns = {#JoinColumn(name = "FUNCTIONALITY_ID")},
inverseJoinColumns = {#JoinColumn(name = "ROLE_ID")})
private List<Role> roleList;
}
Role
#Entity
#Table(name = "ROLE")
public class Role implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ROLE_ID")
private Integer roleId;
#Column(name = "ROLE_NM")
private String roleName;
#Column(name = "ROLE_DESC")
private String roleDesc;
#Column(name = "OBJECT_TYPE")
private String objectType;
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "roleList")
private List<Functionality> functionalityListy;
}
Users
#Entity
#Table(name = "USERS")
public class Users implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "USER_ID")
private Long userId;
#Column(name = "USER_DESC")
private String userDesc;
#Column(name = "FIRST_NM")
private String firstNM;
#Column(name = "LAST_NM")
private String lastNM;
#Column(name = "IS_ENABLED")
private String isEnabled;
}
I have no idea how Role_Member and Role_Member_Entry should be mapped and handled withing object world, could somebody give me some hits? Thanks!
Normally I'd connect Users with Role as Many to Many, but the entity Role_Member_Entry ruins everything.