Create table name from className in Hibernate - java

I have a Class whose objects I want to be able to persist via Hibernate such as:
package my.package
#Entity
#Table(name="hibernatedclass")
public class HibernatedClass {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
#Column(name="firstname")
private String firstname;
[....]
}
As it can be seen the name I have given the table to store the objects of my.package.HibernatedClass is named hibernatedclass.
What I am looking for in an answer is: How can this naming be automatized?
Something that would imho look similar to this pseudo-code.
#Table(name=class.getCanonicalName())

Related

findBy foreign key in Spring Data JPA

I have an entity EncodingResult that references three others. I want to find out how to use the repository's findBy() methods to return an entity based on its foreignKey so that I can, for example, make a GET request passing a Video's foreign key as a parameter and return whether or not there is an EncodingResult containing a Video with the given foreignKey.
How would you go about doing this? I tried reading a bit on EntityGraphs and was rather confused. There also doesn't seem to be a great number of content explaining these parts of the framework.
It would be better if you posted the code for your entities, but from your description, I think you have something like this:
#Entity
public class EncodingResult {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToMany(mappedBy = "encodingResult")
private List<Video> videos=new ArrayList<Video>();
//...boilerplate
}
#Entity
public class Video {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
#ManyToOne
EncodingResult encodingResult;
//...boilerplate
}
So you can define findBy methods in your EncodingResultRepository like so.
public interface EncodingResultRepository extends JpaRespository<EncodingResult, Integer> {
public Optional<EncodingResult> findByVideoName(String name);
public Optional<EncodingResult> findByVideoId(Integer id);
}

Can Hibernate map subset of columns into an internal sub Pojo

I have the following Pojo:
#Entity
#Table(name = "USER")
class User {
#Id
private long id;
private String name;
private int age;
private long lastVisited;
private long lastPlayed;
private long lastPayed;
...
}
I would like somehow if possible to map the Pojo like this:
#Entity
#Table(name = "USER")
class User {
#Id
private long id;
private String name;
private int age;
#Embedded
private UserStatistics statistics;
...
}
#Embeddable
class UserStatistics {
private long lastVisited;
private long lastPlayed;
private long lastPayed;
}
BUT, I DON'T want to move the statistics columns into a new
USER_STATISTICS table and do #OneToOne mapping.
Is there a Hibernate trick I can use here?
Thanks!
What you did is already enough, Hibernate does not require you to define fields for all columns in your table. It's rather the other way around - all non-transient fields should be reflected as columns in the corresponding table either using name defined in #Column annotation or generated using a naming convention used in hibernate configuration.
The example you presented is sufficient and will work, but I wouldn't recommend it as you can have two entities mapping single row at the same time.

How to get the value of the lazy Hibernate field through reflection

I found similar questions, but they did not answer my question.
I have two entities with a many-to-one relationship - unidirectional.
But most importantly, the relationship is lazy. Because it is correct to use a lazy connection, everyone knows it.
Code:
#Entity
public class User implements BaseEntity {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String name;
#ManyToOne(fetch = FetchType.LAZY)
private City city;
}
#Entity
public class City implements BaseEntity {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String name;
}
interface BaseEntity {
void setId(Long id);
Long getId();
}
I wrote a method that allows you to search by the transferred fields of the entity.
An example of how this works:
public class Search<T extends BaseEntity> {
public List<T> getByFields(T entity, List<FieldHolder> data) {
// create criteria with passed field name and value by reflection
}
}
class FieldHolder {
private String fieldName;
private Object value;
/**
* "true" - means that the field "value" contains id related object
* "false" - elementary type like: String, Wrapper, Primitive
*/
private boolean isRelationId;
}
The problem is that problems start when you need to search and related objects - by creating related queries.
The following entry is used to send the associated field: "city.id" and the problem is that when I transfer the essence of the related object (City) it is in a proxy and I cannot get id by reflection from City.
My function works perfectly if you specify:
#ManyToOne(fetch = FetchType.EAGER)
private City city;
But it will greatly affect performance, since I have a lot of related objects. Therefore, I want to solve this problem for a lazy load.
I know that this is not an easy task. But perhaps there is some opportunity to somehow get around this problem.

Hibernate Mapping Only one class

Hibernate Mapping
How to implement such a code?
Each company has two properties, they are company name and estimated annual earnings.
There are two types of companies: 1- Main company, 2 - Subsidiary company.
The company can belong only to one company but can have a few child companies.
public class Company {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String companyName;
private double estimatedAnnualEarnings;
private Company company; // here need to do a #OneToOne
private List<Company> subsidiaryCompany; // here need to do a #OneToMany
}
In your Implementation you should use :
The #Entity annotation in your class level, so the entity can be persisted to database.
The #Column annotation with the companyName and estimatedAnnualEarnings properties, so they can be persisted as columns in the database.
#ManyToOne annotation with the company field, so it can be mapped with a self-reference relationship.
The same goes with the subsidiaryCompany List which needs to be mapped with #OneToMany annotation to have a relationship too.
This is how should be your code:
#Entity
public class Company {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column
private String companyName;
#Column
private double estimatedAnnualEarnings;
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn(name="mainCompanyId")
private Company mainCompany;
#OneToMany(mappedBy="mainCompany")
private List<Company> subsidiaryCompanies;
//getters and setters goes here
}
Note
I changed the name of company field to mainCompany and
subsidiaryCompaniy to subsidiaryCompanies for better readability
and to make it fit the logic better.
If you want to give your entity a different name in the database you
should use #Table(name="differentName") in the class level with
#Entity annotation, the smae thing with the columns you can add
name property to the #Column annotation i.e
#Column(name="company_name") if you want different names.

hibernate for child entity

Quick hibernate question - How can I use Hibernate annotations to define this class as an entity -
public class NativeType {
private long id;
private String name;
private int maxPrecision;
private byte maxScale;
private DataStoreProvider provider;
linked as a Map Collection in the AbstractDataStoreProvider class -
public abstract class AbstractDataStoreProvider implements DataStoreProvider,
Serializable{
private Map<String, NativeType> uniqueNativeTypes;
..
public interface DataStoreProvider {
so I can store this in DB tables like so -
**datastore_provider**
provider_id | provider_name
**native_type**
native_type_id | name | max_precision | max_scale | provider_id
I think its me, but I cant navigate the Hibernate specs very easily. New to Java, and newer to JPA + Hibernate. Appreciate the guidance!
Code Sample
I think you can use the following -
#Entity
#Table(name = "native_type")
public class NativeType {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "native_type_id")
private Long id;
private String name;
#Column(name = "max_precision")
private int maxPrecision;
#Column(name = "max_scale")
private byte maxScale;
#ManyToOne
#JoinColumn(name="provider_id")
private DataStoreProvider provider;
// rest of the class (getter setter etc.)
}
ID Generation
I am assuming you are auto-generating your database ids, hence I marked it with the #GeneratedValue annotation. As for the strategy, I specified AUTO which is only suitable for local experiments. For production-grade application, you'll have to choose between SEQUENCE, IDENTITY, and TABLE.
Relation Mapping
I assumed that you are going to create a DataStoreProvider entity too. In that case, you can specify the relation between them as described above.
Reference
For further reference, you can consult this excellent book.

Categories

Resources