Order by the associate field (OneToMany) - eclipselink

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"

Related

Linq Entity With Return Function

I have 2 tables:
Room_Type (ID_Room_Type, Name_Room_Type)
Room_Room (ID_Room_Type, Number_Room)
How to place a new column Temp in the RoomType table that will take its value as the sum of the rooms from the Room_Room table.
This code does not work :
Private Sub SimpleButton1_Click(sender As Object, e As EventArgs) Handles SimpleButton1.Click
Dim Db As New HotelEntities
Dim s = (From I In Db.Room_Type Select I.ID_Room_Type, I.Name_Room_Type, ColumnTemp = GetTotal_Room(I.ID_Room_Type)).ToList()
Me.DataGridView1.DataSource = s
End Sub
Private Function GetTotal_Room(id_room_type As Int32) As Int32
Dim Db As New HotelEntities
Return (From I In Db.Room_Room Where I.ID_Room_Type = id_room_type).Count
End Function
Message Error :LINQ to Entities does not recognize the method 'Int32
GetTotal_Room(Int32)' method, and this method cannot be translated
into a store expression.
I had a similar problem and I solved it by extracting the list first and then applying linq over it. You can try by altering your code as below.
Dim Db As New HotelEntities
Dim roomTypeList = Db.Room_Type.ToList()
Dim s = (From I In roomTypeList
Select I.ID_Room_Type, I.Name_Room_Type,
ColumnTemp = GetTotal_Room(I.ID_Room_Type)).ToList()
Me.DataGridView1.DataSource = s
Entity Framework will generate Linq query expressions to valid sql query.
As error message explain EF doesn't know how to convert your method GetTotal_Room to valid sql query.
Instead you can get required result from one query, without extra function.
From roomRoom In db.Room_Room
Join roomType In db.Room_Type On roomRoom.ID_Room_Type Equals roomType.ID_Room_Type
Select New With { roomRoom.ID_Room_Type, roomType.Name_Room_Type } Into roomtypes
Group roomtypes By roomtypes Into grouptypes
Select New With
{
Id = grouptypes.Key.ID_Room_Type,
Name = grouptypes.Key.Name_Room_Type,
Total = grouptypes.Count()
}
As additional notice, I don't know context of your application, but based on given sample, I think you can remove some prefixes and suffixes in table and column names
RoomType
Id
Name
Room
TypeId -- reference to RoomType.Id

LINQ fill nested list of Object from query results

I am joining two tables Race and Odds (joined on RaceID) and would like to create an object for each Race with its nested odds. Via LINQ I am able to group the query results into objects but can't populate the nested Odds list for each Race. Any ideas?
Ideally, I should have
obj[0] with RaceID = 1, Odds{1,2,3}
obj[1] with RaceID = 2, Odds{4,5,6,7}
etc
Public Class Race
Private RaceID As Integer
Private Name As String
'other properties here
Private Odds As New List(Of Odds)
End Class
Public Class Odds
Private OddsID As Integer
Private Odds As System.Nullable(Of Decimal)
Private RaceID As Integer
'other properties here
End Class
My function
Dim objRace As New List(Of Race)
Using context As IDataContext = DataContext.Instance()
Dim repository = context.GetRepository(Of Race)()
objRace = repository.Find("SELECT Odds.OddsID, Odds.Odds, Odds.Name, Odds.Type, Odds.DateUTC, Odds.WebsiteName, Odds.RaceID AS RaceID, Race.RaceID AS RaceID,
Race.Name AS RaceName, Race.RaceDate, Race.Location, Race.URL, Race.PortalID AS PortalID, Race.RaceTime
FROM Odds RIGHT OUTER JOIN
Race ON Odds.RaceID = Race.RaceID
WHERE (Race.PortalID = #0)", PortalId)
End Using
LINQ to get objects
Dim result = objRace.GroupBy(Function(records) records.RaceID).[Select](Function(r) New Race() With {
.RaceID = r.Key
.Odds = ' <------ **somehow populate this nested list**
}).ToList()
my query results:
The r should be a implementation of IGrouping. This contains a Key that you are using for your RaceID and it is a IEnumerable itself.
So you can store the Odds by calling r.ToList() or r.ToArray. How ever you want to store them.
I just noticed that you already create the list instance for your Odds in the constructor. You may want to change this, so you can put the collection in directly using the With initialisation.

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
}

How can I use Linq to entities to group a collection without using anonymous types?

The documentation has an example about grouping on multiple properties:
Dim custRegionQuery = From cust In db.Customers _
Group cust.ContactName By Key = New With _
{cust.City, cust.Region} Into grouping = Group
For Each grp In custRegionQuery
Console.WriteLine(vbNewLine & "Location Key: {0}", grp.Key)
For Each listing In grp.grouping
Console.WriteLine(vbTab & "{0}", listing)
Next
Next
Suppose I have a real type (i.e. not anonymous) that has properties for each element of the key, as well as a property for the group, so something a little like:
Public Class CustomerRegionGroup
Public Sub New(city As String, region as String, customers As IEnumerable(Of Customer))
Me.City = city
Me.Region = region
Me.Customers = customers
End Sub
Public Property City As String
Public Property Region As String
Public Property Customers As IEnumerable(Of Customer)
End Class
Is it possible to rewrite the original query to just return IEnumerable(Of CustomerRegionGroup), or do I have to use the anonymous type, and run a second query on the result of the first?
Turns out it was a lot simpler than some of the things I'd tried, as I didn't appreciate that you could just do:
Dim custRegionQuery = From cust In db.Customers _
Group By cust.City, cust.Region _
Into Group _
Select New CustomerRegionGroup(City, Region, Group)

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

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.