Do I need to Set Foreign key value in JPA? - jpa-2.0

I have two table:
CREATE TABLE [LeTYPE](
[LeNAME] [varchar](100) NOT NULL,
[Le_DESC] [varchar](500) NULL,
[LeFOR] [varchar](50) NOT NULL,
CONSTRAINT [PK_LeTYPE] PRIMARY KEY CLUSTERED
(
[LeNAME] ASC
)
)
CREATE TABLE [Le](
[SN] [int] IDENTITY(1,1) NOT NULL,
[LeNAME_FK] [varchar](100) NOT NULL,
[Le_SN] [int] NULL,
[LOWERRANGE] [float] NOT NULL,
[UPPERRANGE] [float] NOT NULL,
[Le_DESC] [varchar](500) NULL,
[COLOR] [varchar](45) NULL,
CONSTRAINT [Le_pk] PRIMARY KEY CLUSTERED
(
[SN] ASC
))
GO
ALTER TABLE [Le] WITH CHECK ADD CONSTRAINT [FK_Le_LeTYPE] FOREIGN KEY([LeNAME_FK])
REFERENCES [LeTYPE] ([LeNAME])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [Le] CHECK CONSTRAINT [FK_Le_LeTYPE]
GO
One tuple in LETYPE will have many LE.
JPA Entity generated by netbeans:
public class Letype implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 100)
#Column(nullable = false, length = 100)
private String Lename;
#Size(max = 500)
#Column(name = "Le_DESC", length = 500)
private String LeDesc;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 50)
#Column(nullable = false, length = 50)
private String Lefor;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "LenameFk", fetch = FetchType.LAZY)
private List<Le> LeList;
}
public class Le implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Column(nullable = false)
private Integer sn;
#Column(name = "Le_SN")
private Integer LeSn;
#Basic(optional = false)
#NotNull
#Column(nullable = false)
private double lowerrange;
#Basic(optional = false)
#NotNull
#Column(nullable = false)
private double upperrange;
#Size(max = 500)
#Column(name = "Le_DESC", length = 500)
private String LeDesc;
#Size(max = 45)
#Column(length = 45)
private String color;
#JoinColumn(name = "LeNAME_FK", referencedColumnName = "LeNAME", nullable = false)
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private Letype LenameFk;
}
Now, What I wanted was if I add a LETYPE from JSF view I would like to add multiple LE also at the same time.
LETYPE
-LE1
-LE2
-LE3
Do I need to set LenameFk manually in Le entity since I am getting
*Cannot insert the value NULL into column 'LENAME_FK'*? Why won't it automatically take it from Le enityt?

Note this snippet of code:
public class Le implements Serializable {
...
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private Letype LenameFk;
...
}
optional = false means any instance of this entity must participate the relation, so, the foreign key field can not be null.

Your right, You need to set LenameFk manually in Le entity.
In General , for Bi-directional one-to-many two way relation , Accessor method should like below and assume entities are Customer and Order and one-to-many relation b/w them.
Customer.java
public Collection<Order> getOrders() {
return Collections.unmodifiableCollection(orders);
}
public void addToOrders(Order value) {
if (!orders.contains(value)) {
orders.add(value);
value.setCustomer(this);
}
}
public void removeFromOrders(Order value) {
if (orders.remove(value)) {
value.setCustomer(null);
}
}
Order.java
public void setCustomer(Customer value) {
if (this.customer != value) {
if (this.customer != null) {
this.customer.removeFromOrders(this);
}
this.customer = value;
if (value != null) {
value.addToOrders(this);
}
}
}
public Customer getCustomer() {
return customer;
}

Related

IdentifierGenerationException: attempted to assign id from null one-to-one property + #MapsId + OneToOne bidirectional

I'm getting error
org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property.
The code snippets:
User.java
#Entity
#Table(schema = "public", name = "user_01")
public class User {
#Id
#GeneratedValue(generator = "UUID")
#GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
#Column(name = "id", updatable = false, nullable = false)
private UUID id;
#OneToOne(cascade = CascadeType.ALL)
#PrimaryKeyJoinColumn
#JoinColumn(name = "user")
private UserInformation userInformation;
UserInformation .java
#Entity
#Table(schema = "public", name = "user_information_06")
public class UserInformation {
#Id
#Column(name = "id")
private UUID id;
#MapsId
#OneToOne(mappedBy = "userInformation")
private User user;
UserInformationService.java
// CREATE
public UserInformationBean createUserInformation(UserInformationBean userInformationBean) {
if(userInformationBean == null || userInformationBean.getUserId() == null)
return null;
User user = userRepository.findById(userInformationBean.getUserId()).orElse(null);
if(user == null)
return null;
UserInformation userInformation = user.getUserInformation();
if(userInformation != null) {
System.err.println("User Information exists !! " + userInformation.getId());
return null;
}
userInformation = new UserInformation();
userInformation.setFirstname(userInformationBean.getFirstname());
userInformation.setLastname(userInformationBean.getLastname());
userInformation.setGender(userInformationBean.getGender());
userInformation.setDateOfBirth(userInformationBean.getDateOfBirth());
userInformation.setProfession(userInformationBean.getProfession());
userInformation.setUpdatedOn(Timestamp.valueOf(LocalDateTime.now()));
user.setUserInformation(userInformation);
userInformation.setUser(user);
user = userRepository.save(user);
return userInformation.toBean();
}
After changing the below:
user = userRepository.save(user);
To:
userInformation = userInformationRepository.save(userInformation);
It works fine! Still want to know the reason and why it can't be persisted via User entity.

How to persist a property of type List<List<Object>> in JPA?

What is the smartest way to get an entity with a field of type List<List> persisted?
#Entity
#Table(name = "Final_Feign_Client_Result")
public class FinalFCResultEntity {
#Id
#Column(name = "id")
#GeneratedValue(strategy = IDENTITY)
private Integer id;
#ElementCollection(targetClass = Object.class)
#CollectionTable(name = "Final_Feign_Client_Result_Columns")
#OnDelete(action = OnDeleteAction.CASCADE)
#JoinColumn(name = "final_feign_client_result_entity_id", nullable = false)
private Set<Object> values;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<Object> getValues() {
return values;
}
public void setValues(Set<Object> values) {
this.values = values;
}
}
I have no problem with columns, but if I try to insert values I get this exception:
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: final_feign_client_result_columns, for columns: [org.hibernate.mapping.Column(values)]
How I can solve this problem?
Hi guidop21 please add
#ElementCollection(targetClass = Object.class)
#CollectionTable(name = "Final_Feign_Client_Result_Columns")
#OnDelete(action = OnDeleteAction.CASCADE)
#JoinColumn(name = "final_feign_client_result_entity_id", nullable = false)
#OneToMany
private List<List<<Object>> values;

java.lang.AssertionError: expected:<ON> but was:<com.spacestudy.model.Account#783f5f71>

I am trying to write a JUnit test case for the following search filter method. I am using Querydsl for the search filter. The following method does not depend on Repository; that is why I am not using mockito. This is the first time I am writing a test case for such a method. Please give any suggestions, if you have any?
public List<Tuple> btnSearchClick(String sClientAcctId, String sAcctDesc, String sInvestigatorName,
String sClientDeptId) throws Exception {
QAccount account = QAccount.account;
QDepartment department = QDepartment.department;
QAccountCPCMapping accountCPCMapping = QAccountCPCMapping.accountCPCMapping;
QInvestigator investigator = QInvestigator.investigator;
JPAQuery<Tuple> query = new JPAQuery<Tuple>(em);
query.select(Projections.bean(Account.class, account.sClientAcctId, account.sAcctDesc, account.sLocation,
Projections.bean(Department.class, department.sDeptName, department.sClientDeptId).as("department"),
Projections.bean(Investigator.class, investigator.sInvestigatorName).as("investigator"),
Projections.bean(AccountCPCMapping.class, accountCPCMapping.sCCPCode).as("accountCPC"))).from(account)
.innerJoin(account.department, department).innerJoin(account.accountCPC, accountCPCMapping)
.innerJoin(account.investigator, investigator).where(account.nInstId.eq(60));
Test case
#Test
public void btnSearchClick() throws Exception {
List<Tuple> account= accountService.btnSearchClick("1124100", sAcctDesc, sInvestigatorName, sClientDeptId);
Department dep = new Department();
dep.setsDeptName("Deans Office");
dep.setsClientDeptId("120010");
Investigator invest = new Investigator();
invest.setsInvestigatorName("Ram, Sri");
AccountCPCMapping cpc = new AccountCPCMapping();
cpc.setsCCPCode("RT");
Account acc = new Account();
acc.setsLocation("ON");
acc.setsAcctDesc("SRIRAM");
acc.setsClientAcctId("1124100");
acc.setInvestigator(invest);
acc.setDepartment(dep);
acc.setAccountCPC(cpc);
accountRepo.save(acc);
assertEquals(acc.getsLocation(), account.get(0));
}
Account.java
#Entity
#Table(name = "account")
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "account_seq_generator")
#SequenceGenerator(name = "account_seq_generator", sequenceName = "account_seq")
#Column(name = "naccount_id")
public Integer nAccountId;
#Column(name = "namount")
public String nAmount;
#Column(name = "sacct_desc")
public String sAcctDesc;
#Column(name = "naccount_cpc_mapping_id")
public Integer nAccountCPCMappingId;
#Column(name = "nindirect_cost_rate")
public Integer nIndiretCostRate;
#Column(name = "nagency_id")
public Integer nAgencyId;
#Column(name = "ndept_id")
public Integer nDeptId;
#Column(name = "sgrant_num")
public String sGrantNum;
#Column(name = "dstart_date")
public Timestamp dStartDate;
#Column(name = "dend_date")
public Timestamp dEndDate;
#Column(name = "slocation")
public String sLocation;
#Column(name = "sclient_acct_id")
public String sClientAcctId;
#Column(name = "ninvestigator_id")
public Integer nInvestigatorId;
#Column(name = "ninst_id")
public Integer nInstId;
#Column(name = "ntemp_account_id")
public Integer nTempAccountId;
#ManyToOne(optional = true, cascade = { CascadeType.MERGE })
#JoinColumn(name = "ndept_id", insertable = false, updatable = false)
public Department department;
#ManyToOne(optional = true, cascade = { CascadeType.ALL })
#JoinColumn(name = "ninvestigator_id", insertable = false, updatable = false)
public Investigator investigator;
#ManyToOne(optional = true, cascade = { CascadeType.ALL })
#JoinColumn(name = "naccount_cpc_mapping_id", insertable = false, updatable = false)
public AccountCPCMapping accountCPC;
// Getter and Setter
Stack Trace
java.lang.AssertionError: expected:<ON> but was:<com.spacestudy.model.Account#783f5f71>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:144)
at com.spacestudy.service.TestAccountService.btnSearchClick(TestAccountService.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
Output from postman
[
{
"sAcctDesc": "SRIRAM",
"sLocation": "ON",
"sClientAcctId": "1124100",
"department": {
"sDeptName": "Deans Office",
"sClientDeptId": "120010"
},
"investigator": {
"sInvestigatorName": "Ram, Sri"
},
"accountCPC": {
"sCCPCode": "RT"
}
}
]
Can anyone please tell me what I am doing wrong in my test case, or suggest an alternative to the code above.
Lists are zero-indexed. That means that if your list has only 1 element, it's index will be 0, not 1.
The element with index 1 is actually the second one (which doesn't exist, thus the index out of bounds).
account.get(1)
should be
account.get(0);

Hibernate criteria cannot fetch rows could not resolve property

Hi i have these 2 basic entity mapping for postgresql db, and i have wrote criteria for
fetching all activated user which have same key it is showing this error
org.hibernate.QueryException: could not resolve property: key.id of: com.sar.dfsapp.modal.ActivatedUser
#Entity
#Table(name = "activated_user")
public class ActivatedUser implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, length = 11)
private long id;
#ManyToOne
#JoinColumn(name = "key_id", nullable = false)
private Key key;
}
#Entity
#Table(name = "key")
public class Key implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, length = 11)
private long id;
#Column(name = "key_code", nullable = false)
private String keyCode;
}
Below is my criteria i have tried.
Criteria c = getSession().createCriteria(ActivatedUser.class);
c.add(Restrictions.eq("key.id", id));
List<ActivatedUser> result = c.list();
try this :
Criteria c = getSession().createCriteria(ActivatedUser.class);
Criteria keyCriteria = criteria.createCriteria("key", CriteriaSpecification.INNER_JOIN);
keyCriteria.add(Restrictions.eq("id", id));
List<ActivatedUser> result = c.list();
it there the same error ?

JPA query filtered by a collection's property in a OneToMany relationship

hope somebaody can help me. I have two entities related OneToMany.
First:
#Entity
#Table(name = "repartos")
#XmlRootElement
public class Repartos 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 = "fecha")
#Temporal(TemporalType.DATE)
private Date fecha;
#OneToMany(cascade = {CascadeType.ALL}, mappedBy = "repartoId")
public List<RepartosDetalle> repartosDetalleList;
.....
And then the another one:
#Entity
#Table(name = "repartos_detalle")
#XmlRootElement
public class RepartosDetalle implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#JoinColumn(name = "reparto_id", referencedColumnName = "id")
#ManyToOne(optional = false)
private Repartos repartoId;
#Column(name = "descargado")
#Convert(converter = BooleanOneZeroConverter.class)
private boolean descargado;
public RepartosDetalle() {
}
public RepartosDetalle(Repartos repartoId) {
this.repartoId = repartoId;
}
public Repartos getRepartoId() {
return repartoId;
}
public void setRepartoId(Repartos repartoId) {
this.repartoId = repartoId;
}
public boolean isDescargado() {
return descargado;
}
public void setDescargado(boolean descargado) {
this.descargado = descargado;
}
}
What I try to get is all the Repartos given a date and where they have al least one RepartosDetalle with the property descargado=TRUE.
I've been trying with the following query but I do't get any result.
#Override
public List<Repartos> buscarPorFechaDescargados(Date searchDate) {
Query q = em.createQuery("SELECT e FROM Repartos e "
+ "WHERE e.fecha = :searchDate"
+ " AND e.repartosDetalleList.descargado=TRUE");
q.setParameter("searchDate", searchDate);
return q.getResultList();
}
Is there a proper way to make this query using one of the collection's property value?
Thanks a lot and nice weekend.
Try to use JOIN operator on these 2 entities - Repartos and RepartosDetalle :
SELECT e FROM Repartos e JOIN RepartosDetalle d
WHERE e.fecha = :searchDate
AND d.descargado = TRUE