Using HQL to query on a Map's Values - dictionary

Let's say I have a map (call it myClass.mapElem<Object, Object>) like so:
Key Val
A X
B Y
C X
I want to write HQL that can query the Values such that I can get back all instances of myClass where mapElem's value is 'X' (where 'X' is a fully populated object-- I just don't want to go through each element and say x.e1 = mapElem.e1 and x.e2=... etc). I know I can do this for the keys by using where ? in index(myClass.mapElem), I just need the corresponding statement for querying the values!
Thanks in advance...
ETA: Not sure if the syntax makes a difference, but the way I am actually querying this is like so:
select myClass.something from myClass mc join myClass.mapElem me where...

You should use elements(). I tried simulating your example with the following class
#Entity
#Table(name="Dummy")
public class TestClass {
private Integer id;
private Map<String, String> myMap;
#Id
#Column(name="DummyId")
#GeneratedValue(generator="native")
#GenericGenerator(name="native", strategy = "native")
public Integer getId() {
return id;
}
#ElementCollection
public Map<String, String> getMyMap() {
return myMap;
}
public void setId(Integer id) {
this.id = id;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
}
And persisted a few instances, which constain maps of a similar structure to what you have in your example. (using < String, String > since the values in your example are strings)
The following query gives me all instances of TestClass, where the map contains a specific value
SELECT DISTINCT myClass
FROM TestClass myClass JOIN myClass.myMap myMap
WHERE ? in elements(myMap)

In my particular case, I ended up having to use an SQL query. Not ideal, but it worked.

Related

How to get string[] array from database with EF core [duplicate]

How can I store an array of doubles to database using Entity Framework Code-First with no impact on the existing code and architecture design?
I've looked at Data Annotation and Fluent API, I've also considered converting the double array to a string of bytes and store that byte to the database in it own column.
I cannot access the public double[] Data { get; set; } property with Fluent API, the error message I then get is:
The type double[] must be a non-nullable value type in order to use
it as parameter 'T'.
The class where Data is stored is successfully stored in the database, and the relationships to this class. I'm only missing the Data column.
You can do a thing like this :
[NotMapped]
public double[] Data
{
get
{
string[] tab = this.InternalData.Split(',');
return new double[] { double.Parse(tab[0]), double.Parse(tab[1]) };
}
set
{
this.InternalData = string.Format("{0},{1}", value[0], value[1]);
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public string InternalData { get; set; }
Thank you all for your inputs, due to your help I was able to track down the best way to solve this. Which is:
public string InternalData { get; set; }
public double[] Data
{
get
{
return Array.ConvertAll(InternalData.Split(';'), Double.Parse);
}
set
{
_data = value;
InternalData = String.Join(";", _data.Select(p => p.ToString()).ToArray());
}
}
Thanks to these stackoverflow posts:
String to Doubles array and
Array of Doubles to a String
I know it is a bit expensive, but you could do this
class Primitive
{
public int PrimitiveId { get; set; }
public double Data { get; set; }
[Required]
public Reference ReferenceClass { get; set; }
}
// This is the class that requires an array of doubles
class Reference
{
// Other EF stuff
// EF-acceptable reference to an 'array' of doubles
public virtual List<Primitive> Data { get; set; }
}
This will now map a single entity (here 'Reference') to a 'list' of your Primitive class. This is basically to allow the SQL database to be happy, and allow you to use your list of data appropriately.
This may not suit your needs, but will be a way to make EF happy.
It would be far easier if you use List<double> rather then double[]. You already have a table that stores your Data values. You probably have foreign key from some table to the table where your double values are stored. Create another model that reflects the table where doubles are stored and add foreign key mappings in the mappings class. That way you will not need to add some complex background logic which retrieves or stores values in a class property.
In my opinion almost all other answers work on the opposite of how it should be.
Entity EF should manage the string and the array must be generated from it. So the array must be whole read and written only when the string is accessed by EF.
A solution involving logic on Data[] is wrong because, as I wrote in a comment, you would run into paradoxical conditions. In all other conditions the variable must remain a pure array.
By putting the "get" and "set" logic in Data[], as I've seen so far, this happens:
1 - Every time an index access is made to the array, the array is automatically recreated from the string. This is a useless work, think of an iteration in a loop...
2 - when you go to set a single element it is not stored because it passes through "get" and not "set".
If you try to declare Data=new []{0,0,0} then set Data[1]=2 , going to re-read Data[1] the result is 0.
My solution is to completely turn the logic around.
public string Data_string
{
get => string.Join(';', Data??Array.Empty());
set => Data= value == null ? Array.Empty<double>() : Array.ConvertAll(value.Split(';',StringSplitOptions.RemoveEmptyEntries), double.Parse);
}
[NotMapped]
public double[] Data {get;set;}
Obviously this only applies to storing and retrieving data on databases, access to Data_string is exclusive to EF.
Once the string is read from the DB it is associated to Data_string which, through set, creates the Data array.
At this point you can work on Data without affecting the string in any way, like a normal array.
When you will ask EF to save in the DB, through the get in the Data_string property, the string will be completely reconstructed based on the Data elements and then stored as a string.
Practically the string is modified only twice, at the moment of reading from the DB and at the moment of saving.
In my opinion this solution is much more efficient than operating continuously on the string.
Nathan White has the best answer (got my vote).
Here is a small improvement over Joffrey Kern's answer to allow lists of any length (untested):
[NotMapped]
public IEnumerable<double> Data
{
get
{
var tab = InternalData.Split(',');
return tab.Select(double.Parse).AsEnumerable();
}
set { InternalData = string.Join(",", value); }
}
[EditorBrowsable(EditorBrowsableState.Never)]
public string InternalData { get; set; }
Don't use double[] use List insted.
Like this.
public class MyModel{
...
public List<MyClass> Data { get; set; }
...
}
public class MyClass{
public int Id { get; set; }
public double Value { get; set; }
}
All that solution that I see there are bad, because:
If you create table, you don't want to store data like this: "99.5,89.65,78.5,15.5" that's not valid! Firstly its a string that means if you can type letter into it and at the moment when your ASP.NET server call double.Parse it will result in FormatException and that you really don't want!
It's slower, because your server must parse the string. Why parse the string instead getting almost ready data from SQL Server to use?
i know this post is Ancient, but in case someone still needs to do something like this, PLEASE DO NOT USE THE ABOVE SOLUTIONS,
as the above solutions are EXTREMELY inefficient (Performance and Disk Space wise).., the best way is to store the array as a Byte array
public byte[] ArrayData;
[NotMapped]
public double[] Array {
get {
var OutputArray = new double[ArrayData.Length / 8];
for (int i = 0;i < ArrayData.Length / 8;i++)
OutputArray[i] = BitConverter.ToDouble(ArrayData, i * 8);
return OutputArray;
}
set {
var OutputData = new byte[value.Length * 8];
for (int i = 0;i < value.Length;i++) {
var BinaryValue = BitConverter.GetBytes(value[i]);
OutputData[(i*8)] = BinaryValue[0];
OutputData[(i*8)+1] = BinaryValue[1];
OutputData[(i*8)+2] = BinaryValue[2];
OutputData[(i*8)+3] = BinaryValue[3];
OutputData[(i*8)+4] = BinaryValue[4];
OutputData[(i*8)+5] = BinaryValue[5];
OutputData[(i*8)+6] = BinaryValue[6];
OutputData[(i*8)+7] = BinaryValue[7];
}
ArrayData = OutputData;
}
}
`
And if you need more performance, you can go for Unsafe code and use pointers .. instead of BitConverter ..
This is way better than saving double values (that can get huge) as string, then spliting the string array !! and then parsing the strings to double !!!
These getter/setters work on the whole array, but if you need to get just one item from the array, you can make a function that gets a single item from the array with a complexity of O(1) :
for Get :
public double Array_GetValue(int Index) {
return BitConverter.ToDouble(ArrayData, Index * 8);
}
for Set :
public void Array_SetValue(int Index, double Value) {
var BinaryValue = BitConverter.GetBytes(Value);
ArrayData[(Index*8)] = BinaryValue[0];
ArrayData[(Index*8)+1] = BinaryValue[1];
ArrayData[(Index*8)+2] = BinaryValue[2];
ArrayData[(Index*8)+3] = BinaryValue[3];
ArrayData[(Index*8)+4] = BinaryValue[4];
ArrayData[(Index*8)+5] = BinaryValue[5];
ArrayData[(Index*8)+6] = BinaryValue[6];
ArrayData[(Index*8)+7] = BinaryValue[7];
}
If your collection can be null or empty, and you want this to be preserved, do this:
[NotMapped]
public double[] Data
{
get => InternalData != null ? Array.ConvertAll(Data.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries), double.Parse) : null;
set => InternalData = value != null ? string.Join(";", value) : null;
}
Also, specify [Column(TypeName = "varchar")] on the string property for a more efficient storage data type.
A perfect enhancement to #Jonas's answer will be to add the necessary annotations. So, a cleaner version would be
[EditorBrowsable(EditorBrowsableState.Never)]
[JsonIgnore]
public string InternalData { get; set; }
[NotMapped]
public double[] Data
{
get => Array.ConvertAll(InternalData.Split(';'), double.Parse);
set
{
InternalData = string.Join(";", value.Select(p => p.ToString(CultureInfo.InvariantCulture)).ToArray());
}
}
The [JsonIgnore] Annotation will ignore the InternalData field from JSON serialization and Swagger UI.
[EditorBrowsable(EditorBrowsableState.Never)] will hide the public method from the IDE IntelliSense

JavaFX Add data to Column's instead of row

Good day,
I have a fixed number of columns in TableView, however I need to populate column by column, not row by row, as one column data depends on the previous one. Is there an example of such thing? I have searched for such way, but unfortunately. Hope I made it understandable.
Since nobody provided me an example, and the comment was not very helpful I manage to solve my problem in the following way (in my case one column result depends on the previous one and the number of elements can be different as well as the number of columns are predefined)
Simple example:
We have an object:
public class Cars{
private String name;
private String company;
private String year;
public Cars(String name,String company,String year){
this.name=name;
this.company=company;
this.year=year;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company= company;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year= year;
}
}
Then we have our table:
public TableView createTable() {
TableView<Cars> table = new TableView<>();
TableColumn<Cars, String> nameyColumn = new TableColumn("Name");
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<Cars, String> companyColumn = new TableColumn<>("Company");
companyColumn.setCellValueFactory(new PropertyValueFactory<>("company"));
TableColumn<Cars, String> yearColumn = new TableColumn<>("Year");
yearColumn.setCellValueFactory(new PropertyValueFactory<>("year"));
table.setItems(makeCars());
table.getColumns().addAll(nameColumn, companyColumn, yearColumn);
return table;
}
Afterwards we generate the information that we want to put into the table and put all the information into, in this case a String Array. So if we have 3 String arrays we can make an ArrayListlist of arrays and populate it with information.
However, the sizes of the String arrays inside the ArrayList have to be predefined, so that you would not get a NullPointException where the at one point you have a car's name and you dont have a year it will be set to an empty automatically, as an empty predefined String array contains null as elements automatically. So in my case I know the max size that one array can be and set all of them to the same size.
And afterwards I just loop through the ArrayList of String Arrays and create objects which I add to the ObservableList ( might be a better way of doing it but I did it this way):
private ObservableList<Cars> makeCars() {
ObservableList<Cars> madeList = FXCollections.observableArrayList();
ArrayList<String[]>arrayOfArrays=new ArrayList<>();
for(int i=0;i<maxRow;i++){
madeList.add(new Cars(arrayOfArrays.get(0)[i],arrayOfArrays.get(1)[i],
arrayOfArrays.get(2)[i]));
}
return madeList;
}
Hope this will helpful to somebody, if there is a better way and I am overdoing it please share.

How to get value of a variable in a long delimited string

In a db table I have a string, such as...
Var1=0;CosType=1;DefaultType=US_Pass;DateYear=1;DateRange=1;ReportFormat=0
I want to create a VB.NET function that has 1 input var, the string (above) and the "token" to get the value for. (The return value is the value of the token.) For example, if I call it (LongString is the string above)....
txtValue.text = MyFunction(LongString,"DefaultType")
So, "US_Pass" would be returned.
What is the most efficient way to code MyFunction?
I've tried something like this...
return LongString.Substring(LongString.IndexOf(input_token) + 12)
I feel I'm close, but so far away.
Thanks!
This works as long as you know the key exists in your string:
public string MyFunction(string longString, string key)
{
return
longString
.Split(';')
.Select(x => x.Split('='))
.ToDictionary(x => x[0], x => x[1])[key];
}
With this code:
string longString = "Var1=0;CosType=1;DefaultType=US_Pass;DateYear=1;DateRange=1;ReportFormat=0";
Console.WriteLine(MyFunction(longString, "DefaultType"));
I get:
US_Pass
As VB.NET:
Public Function MyFunction(longString As String, key As String) As String
Return longString.Split(";"c).Select(Function(x) x.Split("="c)).ToDictionary(Function(x) x(0), Function(x) x(1))(key)
End Function
Split the string into parts at the semi-colons.
Dim parts As String() = LongString.Split(";")
Loop over the parts in a ForEach loop.
Find the part that StartsWith the the token value.
Find the equal sign (IndexOf) and take everything to the right of it (Substring).
That should give you enough to figure it out.
It's probably not a great idea to store data like this in your database. Hopefully you won't need to query these attributes from SQL.
In your case I would create a class to encapsulate the attributes. You pass in the string as a constructor parameter and let the class manage it.
Here's an example in C# that shouldn't be too hard to convert to VB:
public class AttributeCollection
{
private readonly Dictionary<string, string> _attrs;
public AttributeCollection(string values)
{
_attrs = (from v in values.Split(new[] {';'})
select v.Split(new[] {'='})).ToDictionary(i => i[0], i => i[1]);
}
public string this[string name]
{
get { return _attrs[name]; }
set { _attrs[name] = value; }
}
public override string ToString()
{
return string.Join(";", (from a in _attrs select a.Key + "=" + a.Value).ToArray());
}
}

Sorting a list with Objects and A primitive String

I am trying to sort a list as given below.
List dg = new ArrayList();
dg.add(new Dog("one"));
dg.add(new Dog("two"));
dg.add(new Dog("three"));
dg.add(new Dog("four"));
dg.add(new String("Ankit"));
I have tried to implement comparable for Dog class below (not sure if it is useful here)
//Dog class below//
class Dog implements Comparable<Dog>{
String name;
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int compareTo(Dog d){
return this.getName().compareTo(d.getName());
}
The issue is however I write the comparator as given below I get ClassCastException. How to solve this?
class StringComparator implements Comparator {
public int compare(Object d, Object s) {
String p=((Dog)d).getName();
return (p.compareTo(s.toString()));
}
}
//usage of the above comparator
Arrays.sort(odog,sc);
Issue is:
See that to a list you are mixing String object with Dog objects using dg.add(new String("Ankit")); Do you really need string object.
Then you try to sort it using your comparator and your comparator blindly type cast values to Dog object. So when it encounters your String object it tries to type cast it to String object which is not possible (due to Dog not a subclass of String) and hence you get ClassCastException.
I would remove String object from Dog list to resolve the issue.

Google Guava - Filter Multiple Inputs on Single Property

I just got into Google Guava and it seems like a powerful tool and I see how you can use Predicates and filter by a specific property. How you can also chain predicates in FluentIterable My question is what's the best way to filter for a single property.
For example, if I have a collection of Cars. How do I filter the Cars.getPaintColor() to give me cars that are in Black, Red, and Yellow? Creating 3 separate predicates and using FluentIterable seems clumsy. Especially in my use, I could want possibly 10+ filters on the same property and I wouldn't want to create 10 Predicates.
Thanks you!
List<String> colorList = (List<String>)filterCriteria.get("Color");
List<String> makeList = (List<String>)filterCriteria.get("Make");
List<String> rimSizeList = (List<String>)filterCriteria.get("RimSize");
Predicate<String> predColor = Predicates.in(ImmutableSet.copyOf(colorList));
Predicate<CarObj> predDirection2 = Predicates.compose(predColor ,[????] );
Predicate<String> predMakeList = Predicates.in(ImmutableSet.copyOf(makeList));
Predicate<CarObj> predMakeList2 = Predicates.compose(predMakeList, [????] );
Predicate<String> predRimSize = Predicates.in(ImmutableSet.copyOf(rimSizeList));
Predicate<CarObj> predRimSize2 = Predicates.compose(predRimSize, [????] );
Collection<CarObj> filtered = FluentIterable.from(mAllCars)
.filter(predDirection2)
.filter(predMakeList2)
.filter(predRimSize2)
.toList();
Since I am using an List, I used copyOf instead of of when creating ImmutableSet.
I am not sure what to put in the second parameter of the compose. I am guessing it is something like this... in the CarObj class.
static Predicate<CarObj> byColor= new Predicate<CarObj>() {
public boolean apply(CarObj input) {
// What do I put here?
}
};
So, to check if a paint color is one of black, read or yellow, you'd want to create a Predicate that checks if a set contains that color:
Predicate<PaintColor> p = Predicates.in(ImmutableSet.of(
PaintColor.RED, PaintColor.BLACK, PaintColor.YELLOW));
You could then compose that with a Function<Car, PaintColor> that returns the paint color property of your class:
Predicate<Car> p2 = Predicates.compose(p, Car.GET_PAINT_COLOR_FUNCTION);
Edit:
By Car.GET_PAINT_COLOR_FUNCTION I just mean something like this:
public static final Function<Car, PaintColor> GET_PAINT_COLOR_FUNCTION =
new Function<Car, PaintColor>() {
#Override public PaintColor apply(Car car) {
return car.getPaintColor();
}
});
As I said in the comments, you can adapt that to your actual types as needed. For example, make it a Function<CarObj, String> instead.
The alternative to composing your extracting Function<Car, PaintColor> with a Predicates.in() as suggested by ColinD is to write your parameterized Predicate<Car>:
public class CarPaintColorPredicate implements Predicate<Car> {
private final PaintColor paintColor;
public CarPaintColorPredicate(PaintColor paintColor) {
this.paintColor = paintColor;
}
#Override
public boolean apply(#Nullable Car input) {
return input != null && input.getPaintColor() == paintColor;
}
}
which you can then use directly:
FluentIterable.from(cars)
.filter(new CarPaintColorPredicate(PaintColor.RED))
.toList();
or combine for multiple colors:
FluentIterable.from(cars)
.filter(Predicates.or(
new CarPaintColorPredicate(PaintColor.RED),
new CarPaintColorPredicate(PaintColor.BLACK)))
.toList();
or even combine with other types of predicates:
FluentIterable.from(cars)
.filter(new CarPaintColorPredicate(PaintColor.RED))
.filter(new CarMakePredicate("Ferrari"))
.toList();
To be complete, the version with the Function<Car, PaintColor> is as follows:
public enum CarPaintColorFunction implements Function<Car, PaintColor> {
INSTANCE;
#Override
public PaintColor apply(#Nullable Car input) {
return input == null ? null : input.getPaintColor();
}
}
The Function simply returns the value of the property, which is then compared to the collection (hopefully a Set) of accepted values through the Predicate composition:
FluentIterable.from(cars)
.filter(Predicates.compose(
Predicates.in(Sets.immutableEnumSet(PaintColor.RED, PaintColor.BLACK)),
CarPaintColorFunction.INSTANCE))
.toList();
All that's really explained in the Functional Explained page in the Guava Wiki.

Resources