JPQL query for updating an object - sql

I am trying to update a variable named endDate, which is of type LocalDate, using jpql. My query is as follow:
#Modifying
#Query("UPDATE TeamEntity t SET t.coach.endDate = ?2 WHERE t.coach.id = ?1")
public void updateCoachEndDate(long coachId, LocalDate endDate);
part of TeamEntity class is as follow
#Entity
public class TeamEntity{
#ManyToOne
#JoinColumn(name = "coach_id", nullable = true)
private CoachEntity coach;
}
part of CoachEntity class is as follow
#Entity
public class CoachEntity{
#Id
private long id;
private LocalDate endDate
}
When I run a test for it, it seems that it doesn't like
r.coach.endDate = ?2
and it gives me the following error
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "UPDATE Team CROSS[*] JOIN SET END_DATE=? WHERE COACH_ID=? "; expected "., AS, SET"; SQL statement:
update team cross join set end_date=? where coach_id=? [42001-199]
I just wondering if anyone know how to fix this error.

Your descriptions don't match, i.e. I'm unsure where "staff" comes from. Anyhow:
The Hibernate documentation says:
No join, either implicit or explicit, can be specified in a bulk HQL
query. Sub-queries can be used in the where-clause, where the
subqueries themselves may contain joins.
And you have an implicit join in there between TeamEntity and Coach.
So, the next question is, why go through the TeamEntity anyway, since you have the coachId?
update Coach c set c.endDate = ?2 where c.id = ?1
Should do the trick

Related

Empty result on native SQL query on Hibernate

I am trying to develop a simple method to execute sql queries on my application so I can use native sql for certain things.
This is the method I have:
Session session = getReportCsvMgr().getHibernateSession();
session.beginTransaction();
String sql = String.format("select USER_ID from Users where accountid = 'testaaa'");
Object o = session.createSQLQuery(sql).list();
System.out.println(o.toString());
session.close();
I do not get any errors but somehow the object o is empty and the sysout just prints [].
I debugged and the session works. I tested changing the name of the table and indeed it said "table does not exist". I also tried with and update statement, no errors but it does nothing.
Can anybody tell me what I need to do?
Thanks!
Change the line
Object o = session.createSQLQuery(sql).list();
to:
List<Integer> o = session.createSQLQuery(sql).list();
it the USER_ID is integer or to:
List<String> o = session.createSQLQuery(sql).list();
if the USER_ID is string.
Moreover in a query you have not passed params so you can change:
String sql = String.format("select USER_ID from Users where accountid = 'testaaa'");
to simple:
String sql = "select USER_ID from Users where accountid = 'testaaa'";
Either use .uniqueResult() instead of .list() if it only returns one row or change the return type to List<Object[]>

Dealing with LINQ to Objects when object not found

I am using Linq statement as per below to find student name by its ID. It works fine. However there are cases where there is no student with given ID. In those cases an error is thrown "Object reference not set to an instance of an object."
How to efficiently deal with this problem?
Dim Name As String = Students.FirstOrDefault(Function(Student) Student.ID = "NO00007").Name
If you are satisfied with Name being null if there is no matching student, you can use the null conditional operator for member access:
Dim Name As String = Students.FirstOrDefault(Function(Student) Student.ID = "NO00007")?.Name
As usually answer is "it depend" - it depend on how you will use result you will get
If you want get some "default"/empty string instead of name when collection doesn't contain item
Dim result = Students.Where(Function(student) student.ID = "NO00007").
Select(Function(student) student.Name).
DefaultIfEmpty(String.Empty).
First()
Almost same approach if you want to get some "empty" object instead of null
Dim resultStudent = Students.Where(Function(student) student.ID = "NO00007").
DefaultIfEmpty(New Student With { .Name = "empty" }).
First()
From performance point of view approach above are same as FirstOrDefault - but provide little bid better readability(subjective of course)

Compiled LINQ joins

I have got a bit of slack project time so I decided to star in a production of micro optimisation theatre. The app I’m working on is going to be run on some quite low performance tablets so I was looking for ways to speed things up. Given that I’m using LINQ to Entities I looked into precompiled queries to boast performance and so came up with this simple one to return a list of contacts for a given company
Public ReadOnly pContacts_list_query As Func(Of SpiraxDDWEntities, Integer, IQueryable(Of tblContacts)) = _
CompiledQuery.Compile(Of SpiraxDDWEntities, Integer, IQueryable(Of tblContacts))(Function(ctx As SpiraxDDWEntities, pCompany_ABN As Integer) _
From Contact_data In ctx.tblContacts Where Contact_data.AccountNumber = pCompany_ABN
)
Now that’s fine as its just one table so the IQueryable type can be the table name. My question is what if I wanted to precompile a query with joins? For example this one
Dim Quote_QRY = From Quote_data In linEntities.tblQuote
Join Quote_value_data In linEntities.tblQuoteValue On Quote_data.ID Equals Quote_value_data.QuoteID
Join Quote_status_data In linEntities.tblQuoteStatus On Quote_data.Status Equals Quote_status_data.Abbreviation
Where Quote_data.AccountNo = Me.txtCompany_ABN.Text
Select Quote_data.ID, Status = Quote_status_data.Description, Quote_data.Contact, Quote_data.Project, Quote_value_data.QuoteValue
How would I go about that?
Thanks
The join here isn't the issue. The issue is projecting into an anonymous type. In this case, you need to create a named class and project into it in your select clause:
Public Class Quote
Public Property ID As String
Public Property Status As String
Public Property Contact As String
Public Property Project As String
Public Property QuoteValue As String
End Class
Public ReadOnly Quote_query As Func(Of SpiraxDDWEntities, Integer, IQueryable(Of Quotes)) = _
CompiledQuery.Compile(Of SpiraxDDWEntities, Integer, IQueryable(Of Quotes))(Function(ctx As SpiraxDDWEntities, pCompany_ABN As Integer)
From Quote_data In linEntities.tblQuote
Join Quote_value_data In linEntities.tblQuoteValue On Quote_data.ID Equals Quote_value_data.QuoteID
Join Quote_status_data In linEntities.tblQuoteStatus On Quote_data.Status Equals Quote_status_data.Abbreviation
Where Quote_data.AccountNo = Me.txtCompany_ABN.Text
Select New Quote With {
.ID = Quote_data.ID,
.Status = Quote_status_data.Description,
.Contact = Quote_data.Contact,
.Project = Quote_data.Project,
.QuoteValue = Quote_value_data.QuoteValue
}
One additional caveat: I'm not sure off the top of my head if Compiled Query requires that the resulting type be a mapped entity type or not. If so, you may need to alter the EDMX to make EF think that the type is valid. Alternatively, you may want to consider using a Defining query in the CSDL.

LINQ VB.NET variable not found when looping through grouped query

I'm trying to do the following LINQ grouping, which works in the debugger (the results are populated in the GroupedOrders object. But VS 2008 gives me the following error at design time...
Name 'x' is not declared
Dim GroupedOrders = (From m In thisConsultant.orders _
Group m By Key = m.commCode Into Group _
Select commCode = Key, orders = Group)
For Each x In GroupedOrders
Next
Public Structure consultantDetail
Public orders As List(Of orderDetail)
End Structure
Public Structure orderDetail
Public transactionID As Integer
Public qualifyingVolume As Decimal
Public commissionableVolume As Decimal
Public sponsorID As Integer
Public orderDate As DateTime
Public commCode As String
Public commPercentage As Decimal
Public discountPercent As Decimal
End Structure
Do you have Option Infer On?
My guess is that you have Option Strict On and Option Infer Off. To check these settings:
Right-click on your project in the solution explorer
Select Properties
Select the Compile tab on the left
try to surround the Linq query with try-catch. Sometimes, there are error that are not catch directly by VS2008.

nHibernate select query?

I have an ado.net statement I want to convert to use NHibernate:
Dim sql As New StringBuilder()
sql.AppendLine("SELECT r.RoleId, r.RoleName ")
sql.AppendLine("FROM dbo.aspnet_Roles r ")
sql.AppendLine("WHERE r.RoleId IN ")
sql.AppendLine(" (select roleID from dbo.MenuRole where menuId = #MenuId) ")
sql.AppendLine("Order By r.RoleName")
later, I populate the parameter with:
cmd.Parameters.AddWithValue("#MenuId", menuId)
Considering I want to return an: IList(Of AspnetRole)
and I'm using:
Dim managerFactory As IManagerFactory = New ManagerFactory()
Dim roleManager As IAspnetRoleManager = managerFactory.GetAspnetRoleManager()
How do I build and use that query with nHiberate?
(P.S. I am using Codesmithtools and VB.net and VS2008 and SQL Server 2008)
First, you'd have to map the aspnet_roles table and the MenuRole table to their corresponding classes. Once you've mapped them, I'd also map a many-to-one MenuRole property to the AspnetRole class.
Once you've done that the criteria query should look something like this:
Dim c As ICriteria = Session.CreateCriteria(TypeOf(AspnetRole))
c.Add(Restrictions.Eq("Menu.Id", menuId)
return c.List(Of AspnetRole)