HQL - how to query data from one-to-many relationship and condition on second entity field - sql

This is what i expected in SQL query string:
SELECT dbo.FRIEND.FriendId, dbo.FRIEND.MemberId, dbo.FRIEND.FriendMemberId, dbo.FRIEND.DateAdded
FROM dbo.FRIEND INNER JOIN
dbo.MEMBER ON dbo.FRIEND.FriendMemberId = dbo.MEMBER.MemberId
WHERE (dbo.MEMBER.Activate = 1)
This is my entities with relationship :
Entity Friend field
#Id
#Column(name = "[FriendId]")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long friendId;
#Column(name = "[MemberId]")
private Long memberId;
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "[FriendMemberId]")
private Member friendMember;
#Column(name = "[DateAdded]")
private Date dateAdded;
Entity Member field
#Id
#Column(name = "[MemberId]")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long memberId;
#Column(name = "[Activate]", columnDefinition = "boolean default true")
private boolean activate;
Here is my HQL query :
FROM Friend as f Left join f.Member as m WHERE f.MemberId = :memberId AND m.activate = true
but i got error. so how should i write HQL query get data and its condition depend on member.activate ?

You can access subtables using the dot notation and Hibernate will take care of the join for you.
SELECT FROM Friend f WHERE f.friendMember.activate = true
That's part of why HQL is so nice.

Your query has some typo. You should use field name instead of type when you access to field.
Try this:
FROM Friend as f Left join f.friendMember as m WHERE f.memberId = :memberId AND m.activate = true
If you have other problem. Please show me the log.

Related

Data Conversion in Spring

I am new to Spring here, When I use long data type (for storing timestamps) it is converted to Medium Text in SQL and it is causing some problems in my code. Is there any solution to this?
ex:
#Column(columnDefinition = "long default 0")
private long loginfailedtime;
#Column(columnDefinition = "long default 0")
private long lastlogintime;
#Column(columnDefinition = "long default 0")
private long otp_timestamp;
enter image description here
As the value you want to store is time, I would recommend using Date type instance.
#Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Date loginfailedtime;
#Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Date lastlogintime;
#Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Date otp_timestamp;
Also, if you want to use long, in column definition you are using long, where the data type corresponding to the table should be mentioned.
columnDefinition : The SQL fragment that is used when generating the DDL for the column.
For instance,
#Column(name="EMP_PIC", columnDefinition="BLOB NOT NULL")
In JAVA 8, we have below mappings provided.
#Column(name = "local_time", columnDefinition = "TIME")
private LocalTime localTime;
#Column(name = "local_date", columnDefinition = "DATE")
private LocalDate localDate;
#Column(name = "local_date_time", columnDefinition = "TIMESTAMP")
private LocalDateTime localDateTime;
Explore more here => https://www.baeldung.com/jpa-java-time

query to fetch data from a table with restriction on list field mapped as many to many relationship

Kindly help me with hibernate template or detached criteria query, to fetch data from a table Clause. It has a set of Department table (Many to Many relationship). Now, i need list of only those clauses which are associated with any of the department list- List deptIdList (This is the input parameter). I could get the desired result using SQL native query but i want to achieve the result using hql or detached criteria query.
public class Clause {
#Id
#GeneratedValue
#Column(name = "CLAUSE_ID")
private Long clauseId;
#Column(name = "REG_REFERENCE")
private String regulatoryReference;
#Column(name = "REG_REQ")
private String regulatoryRequirement;
#Column(name = "REQ_IMP_RATING")
private String reqImpactRating;
#ManyToMany(fetch=FetchType.EAGER)
#JoinTable(name = "EWMS_CLAUSE_DEPT",
joinColumns = { #JoinColumn(name = "CLAUSE_ID", nullable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "DEPT_ID", nullable = false, updatable = false) }
)
private Set<Department> departmentListForClause;
#Column(name = "CLAUSE_KEY_ACT")
private String keyActivity;
#Column(name = "CLAUSE_TOPIC")
private String clauseTopic;
#Column(name = "CLAUSE_KEY_WORDS")
private String clauseKeywords;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "REG_ID")
private RegulationDetails regulation;
//getter setter methods
}
public class Department {
#Id
#GeneratedValue
#Column(name = "DEPT_ID")
private Long departmentId;
#Column(name = "DEPT_NAME")
private String departmentName;
#Column(name = "TIER1_ID")
private String tierId;
#ManyToMany(/*fetch = FetchType.LAZY,*/ mappedBy = "regulatoryDepartments")
private Set<RegulationDetails> regulationListForDepartment;
#ManyToMany(/*fetch = FetchType.LAZY, */mappedBy = "departmentListForClause")
private Set<Clause> clauseListForDepartment;
//getter setter methods
}

Order by the associate field (OneToMany)

I am trying to sort the Faculty entity by using the JPQL below but I am retrieving too many faculty of the same id.
#NamedQuery(
name = "Faculty.findFacultySortedByPreferredTime",
query = "SELECT f FROM Faculty f JOIN f.preferredTimes p ORDER BY p.day, p.startTime"
),
Here is my Faculty entity I am working
public class Faculty implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String middleName;
private String lastName;
#OneToMany(cascade = CascadeType.PERSIST)
#OrderBy(value = "day, startTime")
private List<PreferredTime> preferredTimes;
// some codes removed
Am I doing it wrong?
For the most part, JPA returns an entity for each row you've selected from the database, so when joining to a 1:M or M:M relationship, you will get more than one instance of an object back. In this case, a Faculty has many preferredTimes. If faculty1 has preferredTimeA and preferredTimeC while faculty2 has preferredTimeB and preferredTimeD, you would get an ordered list of (faculty1, faculty2, faculty1, faculty2) because of the join and ordering you specified.
The DISTINCT keyword is used to filter out non-distinct entities/rows:
"SELECT DISTINCT f FROM Faculty f JOIN f.preferredTimes p ORDER BY p.day, p.startTime"

Select By Key Values from a LINQ Query in a view

I am trying to grab each key value from a LINQ Query and pull them into my view. The LINQ query looks like this:
Public Property ByVDN As IEnumerable
Get
Dim valQ = (From scr In Var.db.CareSideA.ScriptCrossReferences
Join s In Var.db.CareSideA.Scripts On s.ScriptID Equals scr.ScriptID
Join ms In Var.db.CareSideA.MasterScripts On s.MasterScriptID Equals ms.MasterScriptID
Join svce In Var.db.CareSideA.Services On svce.SkillTargetID Equals scr.ForeignKey
Join p In Var.db.CareSideA.Peripherals On svce.PeripheralID Equals p.PeripheralID
Join sm In Var.db.CareSideA.ServiceMembers On svce.SkillTargetID Equals sm.ServiceSkillTargetID
Join sg In Var.db.CareSideA.SkillGroups On sm.SkillGroupSkillTargetID Equals sg.SkillTargetID
Where s.Version = ms.CurrentVersion And scr.TargetType = 1 And svce.PeripheralNumber = Value
Select New With {Key .Service = svce.PeripheralNumber,
Key .ScriptName = ms.EnterpriseName,
Key .Peripheral = p.EnterpriseName,
Key .SkillMapping = sg.PeripheralNumber,
Key .LatestVersion = s.Version,
Key .Created = s.DateTime,
Key .Author = s.Author}).ToList
Return valQ
End Get
Set(value As IEnumerable)
End Set
End Property
Now this does return results but they look like this:
Ideally I'd like to be able to do this:
<table>
For Each Item In Model.ByVDN
Dim i = Item
<tr>
<td>#Html.DisplayFor(Function(m) i.Service)</td>
<td>#Html.DisplayFor(Function(m) i.ScriptName)</td>
<td>#Html.DisplayFor(Function(m) i.Peripheral)</td>
Next
etc...
You can't pass about anonymous objects. Well, you can, but it is not strongly typed. You'll have to define a class with these properties, create IEnumerable of instances of that class and pass that Enumerable to the view. There is no other way.
UPD: see similar question: passing linq select query to the method

complex lists within linq queries with select

I have following linq to entities query, it looks good for compilation but giving me the following error when I run the code. And I want to get a very complex object, which is having some list of derived objects from EDM models. The lists in the below class are not directly from EDM models but they are derived classes from EDM to add more complexity to my problem. Here is the error message. Please help me in resolving this query. I have to get all the data that I want in one linq query thats what my lead is asking me for earlier I had one query for each component and I was adding them. But lead wants it in one query. Please help me in any ways link or code snippet or any suggestion please.
LINQ to Entities does not recognize the method 'System.Collections.Generic.List`1[LNI.WSAW.External.StayAtWork.EmployerAddress] ToList[EmployerAddress](System.Collections.Generic.IEnumerable`1[LNI.WSAW.External.StayAtWork.EmployerAddress])' method, and this method cannot be translated into a store expression.
And Here is the code:
Dim _requestrecord = (From r In Context.Requests.Include("Claims").Include("Employers").Include("EmployerContacts")
Where r.RequestId = RequestId AndAlso r.ManualClaimFlag = ManualClaim
Join c In Context.Claims On r.ClaimId Equals c.ClaimId Where c.ClaimNo.Equals(ClaimNumber)
Join e In Context.Employers On r.Employer.EmployerId Equals e.EmployerId Where e.EmplAccntNo.Equals(EmployerAccountNumber)
Join ec In Context.EmployerContacts On r.EmployerContactId Equals ec.EmployerContactId Where ec.SawGuid.Equals(EmployerContactGuid)
Select New RequestRecord() With { _
.Addresses = (From at In Context.EmployerAddressTypes
Join ea In Context.EmployerAddresses On at.AddressTypeId Equals ea.EmployerAddressType.AddressTypeId Where ea.EmployerId = r.Employer.EmployerId
Select New External.StayAtWork.EmployerAddress() With { _
.AddressLn1 = ea.AddressLn1,
.AddressLn2 = ea.AddressLn2,
.AddressLn3 = ea.AddressLn3,
.AddressType = at.Description,
.BusLocAddressId = ea.BuslocId,
.City = ea.City,
.Country = ea.Country,
.NewSwAddress = ea.NewSwAddressFlag,
.State = ea.St,
.Zip = ea.Zip,
.ZipExt = ea.ZipExt
}).ToList(),
.Employer = New EmployerBaisc() With { _
.EmployerId = e.EmployerId,
.EmployerName = e.EmplName
},
.Exspenses = (From td In Context.TransactionDates Where td.RequestId = RequestId
Join ex In Context.ExpenseTransactions On ex.TransactionDateId Equals td.TransactionDateId
Select New External.StayAtWork.RequestExpense() With { _
.ExpenseAmount = ex.ExpenseAmount,
.ExpenseDate = ex.TransactionDate.TransactionDt.ToString(),
.ExpenseItem = ex.ExpenseItem,
.ExpenseReason = ex.ExpenseReason,
.ExpenseType = ex.ExpenseSubTypeId
}).ToList(),
.Wages = (From td In Context.TransactionDates Where td.RequestId = RequestId
Join wt In Context.WageTransactions On wt.TransactionDateId Equals td.TransactionDateId
Select New External.StayAtWork.RequestWage() With { _
.DailyWage = wt.DailyWagePaidAmount,
.WorkDate = wt.TransactionDate.TransactionDt.ToString(),
.WorkHours = wt.WorkHours.ToString()
}).ToList(),
.Timeloss = (From ctl In Context.ClaimTimelosses
Join clms In Context.Claims On ctl.ClaimId Equals clms.ClaimId Where clms.ClaimId = c.ClaimId
Select New External.StayAtWork.ClaimTimeLoss() With { _
.ClaimNo = ctl.Claim.ClaimNo,
.FromDate = ctl.FromDt.ToString(),
.ToDate = ctl.ToDt.ToString()
}).ToList(),
.Files = (From rfs In Context.RequestFiles
Join reqs In Context.Requests On rfs.RequestId Equals reqs.RequestId Where reqs.RequestId = RequestId
Select New FileBasic() With { _
.FileId = rfs.RequestFileId,
.FileName = rfs.FileName,
.FromDiv = rfs.FromDiv
}).ToList(),
.UiSettings = (From ruis In Context.RequestUis
Join reqs In Context.Requests On ruis.RequestId Equals reqs.RequestId Where reqs.RequestId = RequestId
Select New External.StayAtWork.RequestUI() With { _
.ApfByFax = ruis.ApfByFaxFlag,
.ApfByMail = ruis.ApfByMailFlag,
.ApfLniHas = ruis.ApfLniHasFlag,
.ExpenseByFax = ruis.ExpenseByFaxFlag,
.ExpenseByMail = ruis.ExpenseByMailFlag,
.ExpenseLniHas = ruis.ExpenseLniHasFlag,
.JobByFax = ruis.JobByFaxFlag,
.JobByLni = ruis.JobByLniFlag,
.JobByMail = ruis.JobByMailFlag,
.LastDiv = ruis.LastDiv,
.requestId = ruis.RequestId,
.WageByFax = ruis.WageByFaxFlag,
.WageByMail = ruis.WageByMailFlag,
.WageLniHas = ruis.WageLniHasFlag
}).FirstOrDefault(),
.Request = New RequestBasic() With { _
.RequestId = RequestId,
.Comments = r.Comments,
.InjuredWorkerName = c.WorkerName,
.IsFixedSalary = r.FixedSalaryFlag,
.IsGraveyard = r.GraveyardFlag,
.IsManualClaim = r.ManualClaimFlag,
.JobDescriptBeforeInjury = r.JobDescriptBefore,
.JobDescriptLightDuty = r.JobDescriptLightduty,
.TrackHoursFlag = r.HoursTrackedFlag
}
}).FirstOrDefault()
Response.ResultData = _requestrecord
And here is the the class that I have to get:
Public Class RequestRecord
<DataMember()>
Public Property Request As RequestBasic
<DataMember()>
Public Property Employer As EmployerBaisc
<DataMember()>
Public Property Addresses As List(Of EmployerAddress)
<DataMember()>
Public Property Timeloss As List(Of ClaimTimeLoss)
<DataMember()>
Public Property Wages As List(Of RequestWage)
<DataMember()>
Public Property Exspenses As List(Of RequestExpense)
<DataMember()>
Public Property Files As List(Of FileBasic)
<DataMember()>
Public Property PaidDates As List(Of PaidDate)
<DataMember()>
Public Property UiSettings As RequestUI
End Class
Thanks in advance.