Springboot 3.0 : Hiberanate/JPA 6 validation fail - spring-boot

I am having a method like this
#Modifying( clearAutomatically = true )
#Query( "update versioned LookupMaster set state = 'PUBLISHED' , value = newValue, newValue = null, updatedDate = current_timestamp where ( name = :tableName and state = 'MODIFIED')" )
void commitLookupTableChanges( String tableName );
It was working before springboot 3 upgrade. After springboot upgrade to version 3.0.2 facing validation error like below.
Caused by: java.lang.IllegalArgumentException: org.hibernate.query.SemanticException: The assignment expression type [java.lang.String] did not match the assignment path type [com.nokia.nsw.lookuptable.model.RowState] for the path [alias_2093546827.state] [update versioned LookupMaster set state = 'PUBLISHED' , value = newValue, newValue = null, updatedDate = current_timestamp where ( name = :tableName and state = 'MODIFIED')]
Code for Rowstate :
public enum RowState {
MODIFIED, DELETED, PUBLISHED
}

Remove the single quotes around PUBLISHED and MODIFIED. That is, change the query to:
update versioned LookupMaster set state = PUBLISHED, value = newValue, newValue = null, updatedDate = current_timestamp where ( name = :tableName and state = MODIFIED)
UPDATE
So that is a bug https://hibernate.atlassian.net/browse/HHH-16170 and we will get it fixed.
As a temporary workaround, you can write the query using a full-qualified name for the enum value:
update versioned LookupMaster set state = full.package.name.RowState.PUBLISHED, value = newValue, newValue = null, updatedDate = current_timestamp where ( name = :tableName and state = MODIFIED)

Related

How to fetch the PropertyTemplate by symbolic name and appended to Custom Object class IBM FileNet CE API

How to fetch the PropertyTemplate by symbolic name and appended to Custom Object class through IBM FileNet CE API
You can use the following function to fetch the property template:
public PropertyTemplate getPropertyTemplate(String name, ObjectStore objectStore )
{
String queryFormat = "SELECT [This] FROM [PropertyTemplate] WHERE ([SymbolicName] = ''{0}'')";
SearchScope scope = new SearchScope( objectStore );
String query = MessageFormat.format(queryFormat, name );
RepositoryRowSet fetchRows = scope.fetchRows(new SearchSQL( query ), null, null, null );
Iterator<?> iterator = fetchRows.iterator();
if ( !iterator.hasNext() )
{
return null;
}
RepositoryRow row = (RepositoryRow) iterator.next();
return (PropertyTemplate) row.getProperties().getObjectValue("This");
}
And then use the following code to add the property template to the class:
PropertyTemplate propertyTemplate = getPropertyTemplate(name, objectStore);
ClassDefinition classDefinition = Factory.ClassDefinition.fetchInstance(objectStore, className, null);
PropertyDefinition propertyDefinition = propertyTemplate.createClassProperty();
// Set some additional properties on the property definition
// to override template defaults
classDefinition.get_PropertyDefinitions().add(propertyDefinition);
classDefinition.save(RefreshMode.NO_REFRESH);

Updating Dynamic Columns Issue

I am trying to update values in table emp. Which column to update is dynamic.
public void updateEmployees(List<String> columnDb, List<String> columnValues)
{
var data = ctx.tblEmployee.Where(e => e.Id == empId).Select(e => e).SingleOrDefault();
....
data.columnDb = columnValues; // Pseudo
ctx.tblEmployee.Add(data);
ctx.SaveChanges();
}
How to update columns which are passed dynamically as a parameter?
You can do this with the power of Reflection.
Just iterate through properties of your object and set the value for the properties that you have in your list.
First, let's build a dictionary with property names and values from your parameters to make the value access easier:
var values = columnDb.Zip(columnValues,
(name, value) => new { Name = name, Value = value })
.ToDictionary(x => x.Name, x => x.Value);
Now, iterate through properties and set values:
var data = ctx.tblEmployee.SingleOrDefault(e => e.Id == empId);
foreach(PropertyInfo property in data.GetType().GetProperties())
{
// Check if property should be updated
if(values.ContainsKey(property.Name))
{
var value = values[property.Name];
// Change the type of the value to the type of the property
object converted = Convert.ChangeType(value, property.PropertyType);
// Set the property value
property.SetValue(data,values[property.Name]);
}
}
Of course, the code above assumes that there is a conversion between string and the type of the properties of your data object.

Linq replace null/empty value with another value

In sql server I create views where I can check for null values and replace them with a default if I want (i.e. ISNULL(PrimaryPhone, 'No Primary #') AS PrimaryPhone. I used a lot of views in my asp.net web forms application, but I am now learning MVC 4 and want to start out right.
I have a model, controller and view set up for my client table. I would like to be able to replace null/empty values with ("Not Entered") or something like that.
I believe this needs to go in the controller, please correct me if I'm wrong.
I saw an example that uses hasvalue, but it is not available through intellisense.
How would I replace empty/null values without using DefaultValue in my model?
Thanks
var result = db.Clients.Select(x => new
{
CustomerID = x.CustomerID,
UserID = x.UserID,
FullName = x.FullName,
EmailAdd = x.emailadd.DefaultIfEmpty("No Email"),....
You can use the ?? operator to set a default value when something is null:
var result = db.Clients.Select(x => new
{
CustomerID = x.CustomerID,
UserID = x.UserID,
FullName = x.FullName,
EmailAdd = x.emailadd ?? "No Email", ...
If you need more control, for example checking for both null and empty, you can also use the ?: operator (also known as the "conditional operator" or "ternary operator"):
var result = db.Clients.Select(x => new
{
CustomerID = x.CustomerID,
UserID = x.UserID,
FullName = x.FullName,
EmailAdd = string.IsNullOrEmpty(x.emailadd) ? "No Email" : x.emailadd, ...

How to check for null attributes in LinqToXML expressions?

I have a LinqToXML expression where I am trying to select distinct names based on similar attributes. The code is working great and I've put it below:
var q = xmlDoc.Element("AscentCaptureSetup").Element("FieldTypes")
.Descendants("FieldType")
.Select(c => new { width = c.Attribute("Width").Value,
script = c.Attribute("ScriptName").Value,
sqlType = c.Attribute("SqlType").Value,
enableValues = c.Attribute("EnableValues").Value,
scale = c.Attribute("Scale").Value,
forceMatch = c.Attribute("ForceMatch").Value,
forceMatchCaseSensitive = c.Attribute("ForceMatchCaseSensitive").Value,
sortAlphabetically = c.Attribute("SortAlphabetically").Value,
})
.Distinct();
The problem arises since not all the attributes are required, and if one of them is omitted, for example sortAlphabetically, I get an Object not Referenced error. Makes sense, but it there a way to alter the query to only use assign the new values if the attribute actually exists? (Thereby bypassing any null pointer errors)
Instead of using the Value property (which will blow up on a null reference), simply cast the XAttribute to string - you'll either get the value, or a null reference if the XAttribute reference is null. (XElement works the same way, and this applies to all conversions to nullable types.)
So you'd have:
.Select(c => new {
width = (string) c.Attribute("Width"),
script = (string) c.Attribute("ScriptName"),
sqlType = (string) c.Attribute("SqlType"),
enableValues = (string) c.Attribute("EnableValues"),
scale = (string) c.Attribute("Scale"),
forceMatch = (string) c.Attribute("ForceMatch"),
forceMatchCaseSensitive = (string) c.Attribute("ForceMatchCaseSensitive"),
sortAlphabetically = (string) c.Attribute("SortAlphabetically"),
})
Some of those attributes sound like they should actually be cast to int? or bool?, mind you...

Dealing with a null datetime element within xml using linq

HI
I have an example document that looks like
<ItemEntry>
<PurchaseDate>2010-03-18T20:36:32.81108+13:00</PurchaseDate>
<StoreGUID>0a0324ad-5f99-486a-a2d0-870bc6991e9f</StoreGUID>
<ExpiryDate />
<CardID>111111</CardID>
<PurchaseAmount>0</PurchaseAmount>
<RedeemedAmount />
<EntryType>1</EntryType>
<RedeemedDate />
<SalesAssistantID>0</SalesAssistantID>
</ItemEntry>
As you can see there are couple of elements ExpiryDate and RedeemedDate are are empty.
var q = from c in xml.Elements("ItemEntry")
select new mdDetail {
PurchaseDate = (DateTime)c.Element("PurchaseDate"),
StoreGUID = (Guid)c.Element("StoreGUID"),
ExpiryDate = (DateTime?)c.Element("ExpiryDate")??DateTime.MinValue,
CardID = (int)c.Element("CardID"),
PurchaseAmount = (double)c.Element("PurchaseAmount"),
RedeemedAmount = (double?)c.Element("RedeemedAmount"),
EntryType = (int)c.Element("EntryType"),
RedeemedDate = (DateTime?)c.Element("RedeemedDate") ??DateTime.MinValue,
SalesAssistantID = (int)c.Element("SalesAssistantID"),
}
;
foreach (var item in q)
{
}
I am not sure how to deal with the null element value,
I have tried ??DateTime.MinValue and ??null however both give me a "
String was not recognized as a valid DateTime." error.
Any suggestions?
Thank you
ExpiryDate = String.IsNullOrEmpty((string)c.Element("ExpiryDate"))?
DateTime.MinValue : DateTime.Parse((string)c.Element("ExpiryDate"))
"You could also use null instead of DateTime.MinValue if ExpireyDate is
declared to be nullable"
#Gabe, you can't just use null - you need to use (DateTime?)null because the compiler won't know how to convert null into a DateTime object
So if you want the value to just be a blank (null) this would be the final code:
ExpiryDate = String.IsNullOrEmpty(c.Element("ExpiryDate").Value)?
(DateTime?)null : DateTime.Parse(c.Element("ExpiryDate").Value)
Assuming DateTime is a declared a nullable (DateTime?)

Resources