I'm using PostgreSQL. One of my table fields is an array:
"day_of_month" int[] DEFAULT NULL
But my domain object for this table is List<Integer>. I want to annotate my domain object with #Column(name = "day_of_month") so I can use fetchOneInto(MyDomainType.class). The problem is JOOQ converts int[] field as Integer[] so I have to fetch result, convert Integer[] to List<Integer> and fill my domain object manually. Is there any automatic way to do this?
Unfortunately, the type rewriting system of jOOQ-codegen is not very sophisticated, meaning that "special" data types like arrays or user-defined types are a bit hard to rewrite.
There is a pending feature request #3310 to rectify this, but it won't be before jOOQ 3.5. In the mean time, I'm afraid that you:
Either convert these types yourself:
Post-process the generated jOOQ meta data to patch such Field definitions
Apply Taeir's solution and implement a RecordMapperProvider. This will not modify the array values in jOOQ records, but at least you will be able to map arrays to List when mapping to your MyDomainType.
Update: As a matter of fact, I suspect that #3062 might sufficiently cover your use-case. Maybe, we give this a higher priority for jOOQ 3.4
I'm not sure what you mean with "Automatic", but you can convert an Integer Array into a List of Integers with List<Integer> list = Arrays.asList(array);, where array is your Integer array.
The other way is also possible: Integer[] array = list.toArray(new Integer[0]);.
EDIT:
It might be possible to have JOOQ do this for you. I haven't worked with it myself, but by looking at the documentation, it seems that it is possible to add a RecordMapper to a RecordMapperProvider. With one of these mappers, you can define how certain db types should be converted to java types (I think at least). This is, however, probably a lot more work than just having a small call to Arrays.asList().
Related
I am fetching orders from a backend that has two endpoints, one for fetching a limited number of orders and one for fetching simply the number of total orders available. I can store the orders using a CustomerOrder entity class but how can I store the primitive count value?
Since ObjectBox will not allow boxes of primitive types and requires using entity classes I had to wrap a single (!) Integer inside an entity class. Maybe there is a simpler way to do this?
What does not work but what I basically want to do:
Box<Integer> countBox = boxStore.boxFor(Integer.class);
My current entity wrapper class (still only uses 1 row in the table):
#Entity
public class CustomerOrderCount {
#Id
public Integer count;
}
I simply want to follow best practices and simplify things. Maybe there is an even easier method than using ObjectBox that is still legit that I am not seeing here.
For this can go for SharedPreferences.
Or if you have too many primitive values to store you can go for LevelDB
From the docs:
LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.
The android bindings for LevelDB are available here.
You can also use Hawk. It's another simple key value storage for Android.
Would like opinions on the best way to go.
As you can see int cannot be null.
Where as the object of Integer can.
Problem: Database values with a column that is number can be null or can contain a number.
When the database passes the value of null, then we receive and exception stating that
"primitive values cannot be null"
But when we use Integer class, we are creating that object (which of course is bigger/bulkier than a primitive type int)
So that brings up to me a couple of choices.
Use Integer type.
Set Database column to "default"
Set int to default if there is something different in the database, then accept that
Any other suggestions?
I don't think you must worry about Integer <-> int converting performance (100000000 opsec) if you query database (5000 op/sec). Use boxed types courageously.
Use Hibernate (or similar ORM) and let the framework deal with the database directly. Then you can program it how you like, and not have to deal with converting.
Reinventing the wheel seldom works as well as just using someone else's wheel in the first place, especially when thousands of others already use the same wheel.
My choices:
First- If it is possible and if it is logically ok to set a default in database (might be a FK to a ref table which has all values + a default).
Second - If first is not possible, I would use Integer objects without any reservation. I don't think you will have perf issues. The code will be clean but document in the variable that "can contain null and check for null while working on this variable".
I would always go for something which is more readable and understandable to keep the software maintainable and flexible.
I am using eclipse Tools to generate my Annotated Domain Code Classes.
For the One to Many & Many to Many Relationships, the code generated
used Set type for collections.
I want to change it to List or ArrayList. What should be my configuration
in reveng.xml
Also, what are the standard conversion types between MySQL and Java.
I mean like varchar is converted to string, int to int etc.
Can anyone share a pretty much standard reveng.xml file for type conversions...???
You shouldn't use List by default instead of Set. But if you need it punctually, that can help you:
public <T> List<T> fromSetToList(Set<T> set) {
return new ArrayList<T>(set);
}
Also, what are the standard conversion types between MySQL and Java. I mean like varchar is converted to string, int to int etc.
For reference on Hibernate mappings, I found the following link helpful for basic scenarios. For more complex mappings, refer to the full hibernate documentation.
Hibernate Mapping Cheat Sheet
As for The List vs. Set, Set should actually be the Collection type you should use. The only difference between List and Set is that List implies order of the elements and Set does not allow duplicates. A simple DB record set does not have a specified order and it does not have duplicates, so a Set is appropriate. A List would be useful only if your query did specify order and/or you wanted some kind of UNION which may produce duplicates.
I don't know how to turn your Sets into Lists but I would encourage you to question if you actually want to do so.
I have set up Hibernate to give me a Set<Integer> which I convert internally to and from a Set<MyObjectType> (MyObjectType can be represented by a single integer). That is to say, When Hibernate calls my void setMyObjectTypeCollection(Set<Integer> theSet) method I iterate through all the elements in theSet and convert them to MyObjectType. When Hibernate calls my Set<MyObjectType> getMyObjectTypeCollection() I allocate a new HashSet and convert MyObjectTypes to Integers.
The problem is that every time I call commit, Hibernate deletes everything in the collection and then re-inserts it regardless of whether any element of the collection has changed or even that the collection itself has changed.
While I don't technically consider this a bug, I am afraid that deleting and inserting many rows very often will cause the database to perform unnecessarily slowly.
Is there a way to get Hibernate to recognize that even though I have allocated and returned a different instance of the collection, that the collection actually contains all the items it used to and that there is no need to delete and reinsert them all?
I think the best way to achieve your goal would be to use a UserType. Basically it lets you handle the conversion from SQL to your own objects (back and forth).
You can see an example on how to use it here.
What is the best data structure to store an oracle table that's about 140 rows by 3 columns. I was thinking about a multi dimensional array.
By best I do not necessarily mean most efficient (but i'd be curious to know your opinions) since the program will run as a job with plenty of time to run but I do have some restrictions:
It is possible for multiple keys to be "null" at first. so the first column might have multiple null values. I also need to be able to access elements from the other columns. Anything better than a linear search to access the data?
So again, something like [][][] would work.. but is there something like a 3 column map where I can access by the key or the second column ? I know maps have only two values.
All data will probably be strings or cast as strings.
Thanks
A custom class with 3 fields, and a java.util.List of that class.
There's no benefit in shoe-horning data into arrays in this case, you get no improvement in performance, and certainly no improvement in code maintainability.
This is another example of people writing FORTRAN in an object-oriented language.
Java's about objects. You'd be much better off if you started using objects to abstract your problem, hide details away from clients, and reduce coupling.
What sensible object, with meaningful behavior, do those three items represent? I'd start with that, and worry about the data structures and persistence later.
All data will probably be strings or cast as strings.
This is fine if they really are strings, but I'd encourage you to look deeper and see if you can do better.
For example, if you write an application that uses credit scores you might be tempted to persist it as a number column in a database. But you can benefit from looking at the problem harder and encapsulating that value into a CreditScore object. When you have that, you realize that you can add something like units ("FICO" versus "TransUnion"), scale (range from 0 to 850), and maybe some rich behavior (e.g., rules governing when to reorder the score). You encapsulate everything into a single object instead of scattering the logic for operating on credit scores all over your code base.
Start thinking less in terms of tables and columns and more about objects. Or switch languages. Python has the notion of tuples built in. Maybe that will work better for you.
If you need to access your data by key and by another key, then I would just use 2 maps for that and define a separate class to hold your record.
class Record {
String field1;
String field2;
String field3;
}
and
Map<String, Record> firstKeyMap = new HashMap<String, Record>();
Map<String, Record> secondKeyMap = new HashMap<String, Record>();
I'd create an object which map your record and then create a collection of this object.