Map a column in Hibernate without a property in the Java class - java

Is it possible to map a database column using Hiberanate, so I can use it in HQL queries, but not map it to an actual property in the mapped class?
I don't need this attribute in my class and would like to avoid the clutter of getter and setter, which never should get used anyways.
The usecase I have is to set a flag on certain rows, so a different process will pick up the row and process it. We just have to do an update on the field like this:
update FJ345KJ set wrkxGrumble=1
where wrkxGrumble = 0
and -- more constraints comming here
Since the table and column names forced upon us by the database resemble hashcodes we want to use HQL for the update, which can use nice mapped names. Therefore we need the column mapped in Hibernate.

As far as I know this is not possible. Any mapped column needs a variable in the class.
What you can do is: You map the column with the attribute access = "field" and in the class you declare the variable as private. Then there still is a useless variable declared (this is not a performance issue as the database has to load the row anyway), but no getter and setter is necessary, and as the variable is declared as private it does not influence the interface of your java class, i. e. it is not visible for other classes.

Related

Mapping derived columns to POJOs with RecordMapper in JOOQ

i have a table tickets where i insert ticket and have a field createdBy which stores the UserId Integer of the creator of that record. During fetching I join with users table and concat firstname and last name and my DTO has field createdBy of the concatenated name of creator. How can i map the derived field? this is my reference https://www.jooq.org/doc/3.13/manual/sql-execution/fetching/pojos/ and I cant seem to find such a scenario provided
the issue is not the join. the issue is mapping the string createdBy derived after the join whereas in the record class generated by jooq is an Integer because in the database table i store the userId.
List<MyTickets> mytickets = create.select(....FIELDS).from(TICKETS_).fetch().into(MyTickets.class);
#Override
public Field<Integer> field9() {
return Tickets.TICKETS_.CREATEDBY;
}
In my answer, I will assume that your computed column is going to be called CREATED_BY_NAME, not CREATED_BY, which is a name that's already taken, and to avoid confusion.
If this is something you do frequently, you have a few options that could be interesting to you:
Use views to generate this alternative CREATED_BY_NAME column. A lot of databases can insert into / update views as well, so you won't have a big penalty in using views to replace your tables. To your client logic, the origin of this column will be transparent. If you want to work with UpdatableRecord, you will have to tell jOOQ's code generator what the view's underlying primary key is using the synthetic primary key flag.
Similar to the above views, you could use computed columns on your tables, using the GENERATED ALWAYS AS ... syntax (or whatever your dialect uses for the syntax). Not all dialects support this, but it is a nice feature that turns tables into views without the extra view object.
If you want to keep computing this column manually in your jOOQ code, you could either write your own DTO / POJO objects, or extend the code generator with a custom code section, where you generate the relevant attribute / getter / setter. This approach only works for mutable POJOs, as you cannot modify the constructor of an immutable POJO.
You can also specify a base class for all of your affected POJOs and inject that base class using a generator strategy (programmatic or configurative). The base class could then implement all the getters / setters for columns like CREATED_BY_NAME.
You can also use structural typing instead. You don't have to map all the columns into your POJO. You could also map some columns into your generated POJO (excluding CREATED_BY_NAME) and map the CREATED_BY_NAME column separately. Just keep a reference to your jOOQ Result and/or Record, and perform several map / intoXYZ() calls on it.

Use Transient property in Hibernate

First off, I'm new to Hibernate.
I have a standalone Java application built in Netbeans, trying to keep to the MVC model as much as possible. My model classes resemble the database tables and columns as much as possible. The database is normalized to avoid redundancy.
However, I noticed that it was convenient to have a certain property available in many of my model classes. This property is available in the database, but in most situations it is necessary to do multiple joins to get it.
Therefore, I added this property to my model classes for easier access.
Example:
Object A has a relation with Object B, which has a relation with Object C. Object C has the property X.
The relations are one-to-many; Object A has the primary key of Object B as a column, and so forth.
Now I want to find all Object A connected to property X. I have to do multiple joins to get the answer. Property X also applies to Object A, but I don't want it as a property for Object A in the database, as that is redundancy. In the application, I add this property X to the class of Object Afor convenient access.
Now I want to implement Hibernate instead of my own designed (service) classes, and I'm not sure what to do with this property. I have defined it as 'Transient' in the POJO, but how do I fill this property? If I let Hibernate perform a get tot the database and return the object (Object A) to me, it will not have this property. Do I need to have an extra constructor with this property and transform Hibernate's object to the one containing this property and return that to the original method that asked for it?
What is the correct way to do this?
If you are using Hibernate you probably have something like this in your class A:
#OneToMany
private Collection<B> listOfB;
In B you will have:
#OneToMany
private Collection<C> listOfC;
So when you get the A Entity from your Database you can get x doing:
a.getlistOfB(0).getListOfC(0).getX();

JPA - Using null values in #DiscriminatorValue

I was wondering if I could use the DiscriminatorValue to set apart two subtypes in the following manner:
B extends A
#DiscriminatorValue(null)
A
#DiscriminatorValue("Some-Value")
B extends A
The point is that I want to check if there is a null value in some DiscriminatorType.Char column.
I tried writing "" (empty string) as the value and also null. Niether worked.
The DiscriminatorValue is normally set by the implementation, and you should only need to set it when the implementation cannot properly tell two classes apart, like having duplicate class names or very long class names.
For example, in Hibernate/Postgres, the default discriminator is the simple class name. The only time I have ever had to set it is in deeply nested classes that run on longer than the name limit in the database.
So, long story short, don't specify a discriminator value unless you must.
Annotation do not allow a null indicator, nor does the spec directly support it.
If you are using EclipseLink, you should be able to use a DescriptorCustomizer to add a null classIndicator mapping to the A's ClassDescriptor's inhertiancePolicy.

Java find and compare members by string (maybe JPA feature?)

I've got alot of beans with attributes, which are derived from database tables with JPA. The users shall be able to enter any column name and a value as a string, and the app shall automatically find the correct member in the one of the beans.
I must use JPA, otherwise I would use some JDBC meta data to put all columns and values into a normal map. Is something like this possible with JPA? It only has to work from database to beans, I don't want to persist changes.
If this doesn't work, can I somehow analyze member names programmatically at runtime?
The EntityManagerFactory has a getMetamodel() method, which returns its MetaModel. From this MetaModel, you may ask for the MetaModel of every entity class, and discover all its attributes, their types, etc.
In case the JPA part doesn't work, you can access class members (fields, methods) of your class as follows:
Field[] fs = YouClass.class.getDeclaredFields();
Details for accessing different members are on this link

Mapping class to a table without a table name

I have many tables in my DB with exactly the same structure: same columns names and types.
The only difference between these tables is the their names (which I can only know in runtime).
I would like to create a mapping of a class to a table but giving the name of the table only during runtime (no static #Table annotation).
Is it possible?
Is there any other way to achieve my goal?
Directly - no. Because this is not a regular use-case. Normally you should not have dynamcally-generated tables. It is a valid use when you move some records to an archive table (or tables), but otherwise avoid it.
Anyway, you can make that work: make a native query, and map the result to your non-entity object. You will be able to select from any table and transform the result to an object. However, you can't insert or update that way.
Don't think associating or changing the table mapped to an entity dynamically is possible.
You can check #MappedSuperClass, which will allow you to define all fields in a class once and inherit them, so that there is no repetition and entities are empty class with mappings.
http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e1168
If you know the table name dynamically you can always instantiate the mapped class accordingly.

Categories