EclipseLink: default column names are changed to uppercase - jpa

I have the following entity:
#Entity
public class SomeEntity{
#Id
#Column(name = "id")
private Integer id;
private String foo;
//+getters and setters
}
So, ecpliselink will generate the following query:
SELECT t1.id, t1.FOO FROM ...
I've noticed that all default column names (which I didn't set via #Column) are changed to uppercase. I tried to set eclipselink.jpa.uppercase-column-names to false but it didn't help. How can I make eclipselink get the column names from the class fields without modification?

JPA standardizes the names to uppercase. With the property eclipselink.jpa.uppercase-column-names your're only able to force JDBC return column names in upper case in order to match with default naming in upper case.
If you don't want to use the Annotation #Column to overwrite the default naming of your columns, you could use a SessionCustomizer or a DescriptorCustomizer. Both ways will work with eclipselink and are very well described on this site Link with example of SessionCustomizer & :DescriptorCustomizer

Related

Support for Spring Data JPA multiple dataasource configuration for implicit column names from model class in accordance with table columns

#Column(length = 11)
private String mobileNo;
#Column(length = 20)
private String accountType;
The above is my entity class where i did not define any explicit column names under #column for my variables.
The corresponding column names for the above variables in my table are as mobile_no and account_type respectively - though my entity class variables and column names are bit different but it was working - as spring jpa was handling that naming conventions implicitly.
Now i have defined connections to multiple datasources by defing two configuration classes for two datasorces - but now the implicit #column names as mentioned above is not working.
I dont want to mention the explicit column names with #column in my entity class -
Need any suggestions to make it work with multiple datasorce configurations also - in the same way as it used to work with implicit column names with single database configuration.

PostgreSQL function used in QueryDSL is not working, returns ERROR: syntax error at or near "."

This is my very first question on stackoverflow, so sorry in advance if anything is not as precise as it should be
In my project, I use Hibernate (as ORM framework) with QueryDSL lib, PostgreSQL as a database.
Basically, I need to check the size of a list 'arr', which is a property of some 'X' class, so I googled and found a way to use postgres functions with querydsl as follows (before you ask, I can't use native queries by the requirements):
BooleanBuilder builder = new BooleanBuilder();
builder.and(Expressions.booleanTemplate("function('array_length', {0})", qX.arr)
.castToNum(Integer.class).gt(0));
Everything compiles fine, but when the repository method is being called, I get an error:
ERROR: syntax error at or near "." Position: ...
I checked everything, but there are no "." in that position and near positions as well.
However, after setting spring.jpa.show-sql=true I found out that there is indeed a "." symbol somewhere in that position, and the result SQL statement looks like this:
... and cast(array_length(.) as int4)>?
which means, that JPA can't put my 'arr' inside the array_length() function (is that so?)
Why does this happen? Am I doing something wrong?
Thank you in advance
My entity class looks like that:
#EqualsAndHashCode(callSuper = true)
#Entity
#Table
#Data
#NoArgsConstructor
#TypeDefs({
#TypeDef(name = "list-array", typeClass = ListArrayType.class)
})
public class X extends BaseClass {
// private fields
#Type(type = "list-array")
#Column(name = "arr", columnDefinition = "bigint[]")
#ElementCollection
#OrderColumn
private List<Long> arr;
}
I tried without #ElementCollection and #OrderColumn annotations but that gives me cast errors
#ElementCollection and #OrderColumn are causing a first problem here. After they are removed (and the schema is setup correctly), the function call (SQL template) needs to be corrected.
The problem with #ElementCollection and #OrderColumn is that they represent an alternative approach for storing lists/arrays as part of an entity.
#ElementCollection stores the elements in a separate table, with each element in a separate row (each referencing the entity). To "remember" the correct order, an #OrderColumn is needed as part of the separate table, since rows are returned in arbitrary order if no order is specified (https://stackoverflow.com/a/20050403).
In contrast, ListArrayType and #Column(columnDefinition = "bigint[]") will enable saving the sequence of elements in one column of an entity row. Therefore, no separate table is used, and since the elements are not saved in separate rows, no additional order information is needed.
So without #ElementCollection and #OrderColumn the list mapping is already correctly setup. Be aware that your schema might currently be in a bad state, and you need to make sure that there is a bigint[] column in the entity table (can e.g. be auto-created by hibernate when #ElementCollection and #OrderColumn are removed).
2. Fixing the PostgresQL function call: array_length needs a second argument indicating the dimension of the array along which the length is returned (https://www.postgresql.org/docs/current/functions-array.html). So specifying the template string as follows should get you the correct result:
"function('array_length', {0}, 1)"
("1" being the requested array dimension).

JPA how ensure uniqueness over 2 fields, string and boolean

I want to create an entity containing 2 fields that need to be unique in together. One of the fields is a Boolean:
#Entity
public class SoldToCountry {
private String countryId;
private Boolean isInt;
}
For a given String there should never exist more than 2 entries one with isInt:true and the other isInt:false.
I read the doc about #Id but it seems that Boolean is not supported. For me it would also be ok to have a unique constraint spanned over both fields and using a generated id.
What is the best way to get this constraint via JPA?
If your table has really two fields only, and you want they are unique, then they should be the composite PK of the table. Take a look at How to create and handle composite primary key in JPA
If, instead, you have another PK, consider Sebastian's comment.

Map two fields to one database column

Question: Am I somehow able to map two fields of my Entity class to only one Column in the Database?
Scenario: The database is not fully normalized. There exists one Column which contains a composite information. It is not my actual use case, but an comprehensible example might be X- and Y-coordinate of a point in the plane. So the Database may contain a String 12:45 and the Entity class should contain only two integer field x width value 12 and ywith value 45.
Currently the Entity class has just two additional getter and setter for x and y and performs the proper translation. But I am wondering if there is a way to let JPA do this for me magically in the background.
I am already working with custom converter classes, e.g. for a proper mapping between between enums and database columns, but this works only for a "one-to-one" mapping between the field in the Entity class and the column in the database.
Of course it would be the most preferable way to redesign the table in the database, but that's not an option at the moment.
Vendor specific solutions are also fine.
2 Entity fields into one database column can be done fairly simply by specifying JPA use your accessor in the entity to handle the conversion:
#Entity
#Access(AccessType.FIELD)
class myEntity {
#Id
int id;
#Transient
String x;
#Transient
String y;
#Mutable //EclipseLink specific to prevent change tracking issues
#Access(AccessType.PROPERTY)
#Column(name="yourDatabaseFieldName")
private String getCoords() {
return x+":"+y;
}
private void setCoords(String coords) {
//parse the string and set x+y.
}
EclipseLink and Hibernate have transformation mappings that are able to handle the reverse; 2 or more database fields into one java property but this is outside of JPA.

How to create a composite primary key which contains a #ManyToOne attribute as an #EmbeddedId in JPA?

I'm asking and answering my own question, but i'm not assuming i have the best answer. If you have a better one, please post it!
Related questions:
How to set a backreference from an #EmbeddedId in JPA
hibernate mapping where embeddedid (?)
JPA Compound key with #EmbeddedId
I have a pair of classes which are in a simple aggregation relationship: any instance of one owns some number of instances of the other. The owning class has some sort of primary key of its own, and the owned class has a many-to-one to this class via a corresponding foreign key. I would like the owned class to have a primary key comprising that foreign key plus some additional information.
For the sake of argument, let's use those perennial favourites, Order and OrderLine.
The SQL looks something like this:
-- 'order' may have been a poor choice of name, given that it's an SQL keyword!
create table Order_ (
orderId integer primary key
);
create table OrderLine (
orderId integer not null references Order_,
lineNo integer not null,
primary key (orderId, lineNo)
);
I would like to map this into Java using JPA. Order is trivial, and OrderLine can be handled with an #IdClass. Here's the code for that - the code is fairly conventional, and i hope you'll forgive my idiosyncrasies.
However, using #IdClass involves writing an ID class which duplicates the fields in the OrderLine. I would like to avoid that duplication, so i would like to use #EmbeddedId instead.
However, a naive attempt to do this fails:
#Embeddable
public class OrderLineKey {
#ManyToOne
private Order order;
private int lineNo;
}
OpenJPA rejects the use of that as an #EmbeddedId. I haven't tried other providers, but i wouldn't expect them to succeed, because the JPA specification requires that the fields making up an ID class be basic, not relationships.
So, what can i do? How can i write a class whose key contains #ManyToOne relationship, but is handled as an #EmbeddedId?
I don't know of a way to do this which doesn't involve duplicating any fields (sorry!). But it can be done in a straightforward and standard way that involves duplicating only the relationship fields. The key is the #MapsId annotation introduced in JPA 2.
The embeddable key class looks like this:
#Embeddable
public class OrderLineKey {
private int orderId;
private int lineNo;
}
And the embedding entity class looks like this:
#Entity
public class OrderLine{
#EmbeddedId
private OrderLineKey id;
#ManyToOne
#MapsId("orderId")
private Order order;
}
The #MapsId annotation declares that the relationship field to which it is applied effectively re-maps a basic field from the embedded ID.
Here's the code for OrderId.