how to update select column in Spring data? - spring

Please check the below query I am trying to update a row by the composite key
my key combination is like:
int id
int versionId
String languageId
and query is:
#Transactional
#Modifying
#Query("update languageEntity l set l.language = :language where l.languageId = :languageId")
int UpdateProcessLanguage(#Param("language ") String processDesTranslation, #Param("languageId ") UserLanguageId languageId);
I am not getting any exception. function is returning 0, means no row effected.
please check what is worng.

It's hard to say without knowing the data. As a first step I would log the generated SQL statements (see how to log sql statements in spring-boot) and check if they look right.

Why you dont wan't to use save() method for that? Just change language property on your object and pass it to the save method. It will update the row.

Related

Getting Second Order SQL Injection in Spring Hibernate

I am facing Second Order SQL Injection in the Spring-Hibernate application after scanning through the Checkmarx tool, I have gone through multiple questions in StackOverflow and in other platforms as well but did not get the right finding.
could you please look into the below code snip,
public String getOrderId(order_name){
String returnId= null;
Query query = entityManager.createNativeQuery("select order_id from order where order_name=?");
List<String> dataset = query.setParameter(1,order_name).getResultList();
if(dataset!=null){
returnId = dataset. Get(0);
}
return returnId;
}
In this above method, while calling getResultList(), getting a high vulnerability issue that, this method returns data flows through the code without being properly sanitized or validated, and eventually used in further database query in the method.
Earlier code was like this,
public String getOrderId(order_name){
String returnId= null;
String q = "select order_id from order where order_name="+order_name;
Query query = entityManager.createNativeQuery(q);
and directly it was used as a string append in query, which I have modified with set parameter,
Query query = entityManager.createNativeQuery("select order_id from order where order_name=?");
List<String> dataset = query.setParameter(1,order_name).getResultList();
but still after getting data from query.getResultSet(), it is asking for sanitizing and validating the data before use in further database query method.
and this return data is being used in further query like select * from return_Data where clause. (properly used in where clause to set parameter to avoid SQL injection).
and in the above query is used in another method where we pass return_Data as input to it.
could you please help here to know what checks and validation can be added to overcome this type of issue. Thanks in advance for prompt response.

Difference between New/AndNew by New() in Genexus

How is the difference between this two news?
New
ProductId = &ProductId
ProductPriceListDate = &Today
ProductPriceListPrice = &price
EndNew
and
&Product = new()
&Product.ProductId = &ProductId
&Product.ProductPriceListDate = &Today
&Product.ProductPriceListPrice = &price
commit
Supossing i don't fill this properties, in both way the record will be inserted with null or it will be inserted with empty ('') and 0?
First option is inserting a record directly in the database and null or empty value will be used depending on Initialize not referenced attritutes property.
Second option I think that you're using a Business Component. This case is quite different because is not only inserting a record but triggering transaction rules.
Anyway, in this case "empty" is stored
Note: it seems that you forgot to include save() method in the second option.

SimpleJpaRepository Count Query

I've modified an existing RESTful/JDBC application i have to work with new features in Spring 4... specifically the JpaRepository. It will:
1) Retrieve a list of transactions for a specified date. This works fine
2) Retrieve a count of transactions by type for a specified date. This is not working as expected.
The queries are setup similarly, but the actual return types are very different.
I have POJOs for each query
My transactions JPA respository looks like:
public interface MyTransactionsRepository extends JpaRepository<MyTransactions, Long>
//My query works like a charm.
#Query( value = "SELECT * from ACTIVITI_TMP.BATCH_TABLE WHERE TO_CHAR(last_action, 'YYYY-MM-DD') = ?1", nativeQuery = true )
List< MyTransactions > findAllBy_ToChar_LastAction( String lastActionDateString );
This returns a list of MyTransactions objects as expected. Debugging, i see the returned object as ArrayList. Looking inside the elementData, I see that each object is, as expected, a MyTransactions object.
My second repository/query is where i'm having troubles.
public interface MyCountsRepository extends JpaRepository<MyCounts, Long>
#Query( value = "SELECT send_method, COUNT(*) AS counter FROM ACTIVITI_TMP.BATCH_TABLE WHERE TO_CHAR(last_action, 'YYYY-MM-DD') = ?1 GROUP BY send_method ORDER BY send_method", nativeQuery = true )
List<MyCounts> countBy_ToChar_LastAction( String lastActionDateString );
This DOES NOT return List as expected.
The object that holds the returned data was originally defined as List, but when I inspect this object in Eclipse, I see instead that it is holding an ArrayList. Drilling down to the elementData, each object is actually an Object[2]... NOT a MyCounts object.
I've modified the MyCountsRepository query as follows
ArrayList<Object[]> countBy_ToChar_LastAction( String lastActionDateString );
Then, inside my controller class, I create a MyCounts object for each element in List and then return List
This works, but... I don't understand why i have to go thru all this?
I can query a view as easily as a table.
Why doesn't JPA/Hibernate treat this as a simple 2 column table? send_method varchar(x) and count (int or long)
I know there are issues or nuances for how JPA treats queries with counts in them, but i've not seen anything like this referenced.
Many thanks for any help you can provide in clarifying this issue.
Anthony
That is the expected behaviour when you're doing a "group by". It will not map to a specific entity. Only way this might work is if you had a view in your database that summarized the data by send_method and you could map an entity to it.

Linq to entity update query not updating the table

Its just a simple Linq to Entity update query i tried with the following code but it doesn't update the "User" column in the DB.
Its not even throwing any exception also,please some one point me what am missing here.
MyEntities db = new MyEntities ();
var query = from SEVTs in db.SEVTs
where SESID == "4747747"
select SEVTs;
foreach (var SEVTs in query) {
SEVTs.USER = "Test";
}
db.SaveChanges();
Quite interesting, when i try the follwing query in the sql server its not update the record
update Schedwin.SEVT
set
USER3='Test'
Where
SESID='4747747' // here i pass the value as a string
SESID data type is CHAR and its a primary key. if i pass the value as SESID=4747747 then it update that record.
Please ignore my question.
Here what i missed my input value SESID == "4747747" //this have whitespace that's why it didn't updated that particular record.
Thanks All
You are nor modifying SEVTs.USER, but some local variable.
(BTW: create a context in a using construct)

LINQ to SQL -

I'm attempting to use LINQ to insert a record into a child table and I'm
receiving a "Specified cast is not valid" error that has something to do w/
the keys involved. The stack trace is:
Message: Specified cast is not valid.
Type: System.InvalidCastException
Source: System.Data.Linq TargetSite:
Boolean
TryCreateKeyFromValues(System.Object[],
V ByRef) HelpLink: null Stack: at
System.Data.Linq.IdentityManager.StandardIdentityManager.SingleKeyManager2.TryCreateKeyFromValues(Object[]
values, V& v) at
System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache2.Find(Object[]
keyValues) at
System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType
type, Object[] keyValues) at
System.Data.Linq.CommonDataServices.GetCachedObject(MetaType
type, Object[] keyValues) at
System.Data.Linq.ChangeProcessor.GetOtherItem(MetaAssociation
assoc, Object instance) at
System.Data.Linq.ChangeProcessor.BuildEdgeMaps()
at
System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode
failureMode) at
System.Data.Linq.DataContext.SubmitChanges(ConflictMode
failureMode) at
System.Data.Linq.DataContext.SubmitChanges()
(.....)
This error is being thrown on the following code:
ResponseDataContext db = new ResponseDataContext(m_ConnectionString);
CodebookVersion codebookVersion = db.CodebookVersions.Single(cv => cv.VersionTag == m_CodebookVersionTag);
ResponseCode rc = new ResponseCode()
{
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
codebookVersion.ResponseCodes.Add(rc);
db.SubmitChanges(); //exception gets thrown here
The tables in question have a FK relationship between the two of them.
The parent table's column is called 'id', is the PK, and is of type: INT NOT NULL IDENTITY
The child table's column is called 'responseCodeTableId' and is of type: INT NOT NULL.
codebookVersion (parent class) maps to table tblResponseCodeTable
responseCode (childClass) maps to table tblResponseCode
If I execute SQL directly, it works. e.g.
INSERT INTO tblResponseCode
(responseCodeTableId, surveyQuestionName, code, description)
VALUES (13683, 'Q11', 3, 'Yet another code')
Updates to the same class work properly. e.g.
codebookVersion.ResponseCodes[0].Description = "BlahBlahBlah";
db.SubmitChanges(); //no exception - change is committed to db
I've examined the variable, rc, after the .Add() operation and it does, indeed, receive the proper responseCodeTableId, just as I would expect since I'm adding it to that collection.
tblResponseCodeTable's full definition:
COLUMN_NAME TYPE_NAME
id int identity
responseCodeTableId int
surveyQuestionName nvarchar
code smallint
description nvarchar
dtCreate smalldatetime
dtCreate has a default value of GetDate().
The only other bit of useful information that I can think of is that no SQL
is ever tried against the database, so LINQ is blowing up before it ever
tries (hence the error not being a SqlException). I've profiled and verified
that no attempt is made to execute any statements on the database.
I've read around and seen the problem when you have a relationship to a non PK field, but that doesn't fit my case.
Can anyone shed any light on this situation for me? What incredibly obvious thing am I missing here?
Many thanks.
Paul Prewett
Post up the schema of the parent table.
if you look here, some other people have had your problem.
http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3493504&SiteID=1
It appears that Linq2SQL has trouble mapping some foreign keys to some primary keys. One guy had a resolution, but I think you are already mapping to an IDENTITY column.
Since the database isn't being called I think you have to look at the mappings linq to sql is using. What does the Association look like? There should be an Association on both the parent and child classes.
Take a look at the linq to sql Association between the two classes. The Association should have a ThisKey property. The cast that is failing is trying to cast the value of the property that ThisKey points to, I think.
As far as I can tell there can be a problem when there is more than one key and the type of the first key does not match the type that ThisKey points too. I'm not sure how linq would determine what the first key is.
From the looks of it you only have one key and one foreign key so that shouldn't be the problem, but the designer, if you are using it, has been known to get creative.
I'm pretty much guessing, but this looks like something I've seen before.
Is this an example of this bug? If so, try running your code in .NET 4.0 now that the beta is out.
If, like me, you aren't ready to start using the beta, you may be able to work around the problem. The issue seems to be that LINQ does not properly support relationships defined on non-primary key fields. However, the term "primary key" does not refer to the primary key defined on the SQL table, but the primary key defined in the LINQ designer.
If you dragged your tables into the designer, then Visual Studio automatically inspects the primary key defined in the database and marks the corresponding class field(s) as "primary keys". However, these do not need to correspond to each other. You can remove the key Visual Studio chose for you, and pick another field (or group of fields). Of course, you need to make sure this is logical (you should have a unique constraint in the database on the field/fields you choose).
So I had 2 tables/classes related to eachother using an alternative key. The parent table had 2 keys: a surrogate primary key defined as an int, and an alternative natural key defined as a string. In the LINQ designer, I had defined the association using the alternative key, and I experienced the InvalidCastException whenever trying to update that association field on the child object.
To work around this, I went into the LINQ designer, selected the int, and then changed the Primary Key property from True to False. Then I chose the string, and set it's Primary Key property to True. Recompiled, retested, and the InvalidCastException is gone.
Looking at your screen shot it looks like you may be able to fix your issue by changing the LINQ primary key on ResponseCode from ResponseCode.ID to ResponseCode.ResponseCodeTableID
ResponseCode rc = new ResponseCode()
{
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
and:
INSERT INTO tblResponseCode
(responseCodeTableId, surveyQuestionName, code, description)
VALUES (13683, 'Q11', 3, 'Yet another code')
Are not the same, you are not passing in the foreign key reference. Now, I'm huge n00b at LINQ2SQL, but I'd wager that LINQ2SQL is not smart enough to do that for you, and it expects it as the first parameter of the anonymous dictionary, and is trying to cast a string to an integer.
Just some ideas.
This block:
codebookVersion.ResponseCodes.Add(rc);
db.SubmitChanges(); //exception gets thrown here
Can you try InsertOnSubmit instead of Add? i.e.
codebookVersion.ResponseCodes.InsertOnSubmit(rc);
I think Add is not meant to be used to insert records if my memory serves me right. InsertOnSubmit is the one to use.
To try and narrow down the culprit.
Have you tried replacing the anonymous dictionary with something like:
ResponseCode rc = new ResponseCode();
rc.SurveyQuestName = "Q11";
rc.Code = 3;
rc.Description = "Yet Another Code";
I've yet to really work with .NET 3.5 yet (day job is still all 2.0), so I'm wondering if there is an issue with passing the data using the anonymous dictionary (The cases don't match the SQL Columns for one).
Yea, I've read that and other posts, but it always seems to involve someone linking up to a field that simply has a unique contraint. Or in this guy's case (which does sound exactly like mine), he didn't get a solution.
Here's the parent table:
tblResponseTable definition (which maps to CodebookVersion)
COLUMN_NAME TYPE_NAME
id int identity
versionTag nvarchar
responseVersionTag nvarchar
versionTag does have a unique contraint on it, but that's not represented anywhere that I can see in the LINQ-to-SQL stuff - and since nothing ever goes to the database... still stuck.
Mike, I hear you. But no matter where I look, everything looks correct. I've checked and rechecked that the ResponseTableId is an int and that Id is an int. They're defined as such in the designer and when I go look at the generated code, everything again appears to be in order.
I've examined the associations. Here they are:
[Table(Name="dbo.tblResponseCode")]
public partial class ResponseCode : ...
...
[Association(Name="CodebookVersion_tblResponseCode", Storage="_CodebookVersion", ThisKey="ResponseCodeTableId", OtherKey="Id", IsForeignKey=true)]
public CodebookVersion CodebookVersion
{
...
}
[Table(Name="dbo.tblResponseCodeTable")]
public partial class CodebookVersion : ...
...
[Association(Name="CodebookVersion_tblResponseCode", Storage="_ResponseCodes", ThisKey="Id", OtherKey="ResponseCodeTableId")]
public EntitySet<ResponseCode> ResponseCodes
{
...
}
And a screenshot of the association in case that will help:
Any further thoughts?
ResponseCode rc = new ResponseCode()
{
CodebookVersion = codebookVersion,
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
db.ResponseCodes.InsertOnSubmit(rc);
db.SubmitChanges();
You may want to check to see that any fields in your database tables which are set by the db server when inserting a new record have that reflected in the Linq to SQL diagram. If you select a field on the Linq to SQL diagram and view its properties you will see a field called "Auto Generated Value" which if set to true will ensure all new records take on the default value specified in the database.
LINQ to SQL has been deprecated, FYI - http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx.
I ran into a very similar problem. I'll link you over to my wordy post: http://forums.asp.net/p/1223080/2763049.aspx
And I'll also offer a solution, just a guess...
ResponseDataContext db = new ResponseDataContext(m_ConnectionString);
CodebookVersion codebookVersion = db.CodebookVersions.Single(cv => cv.VersionTag == m_CodebookVersionTag);
ResponseCode rc = new ResponseCode()
{
ResponseCodeTableId = codebookVersion.Id,
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
db.ResponseCodes.InsertOnSubmit(rc);
db.SubmitChanges();
Somewhere in your object graph there is a conversion error, the underlying data model (or the Linq To SQL model) has changed. This is typically something like NVARCHAR(1) -> CHAR when it should be STRING, or something similar.
This error is not fun to hunt down, hopefully your object model is small.
We had a similar problem, caused by using non-integer keys. Details and hotfix number are here: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=351358

Resources