I've got a Category Hibernate model:
#Entity
#Table(name = "category")
public class Category {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "type")
private String type;
which have a type string field. Also I've got a Java enum which represent a type of a category:
public enum CategoryType {
INCOME, OUTCOME;
}
which I would like to use instead of the string type. The SQL accepts two distinct values in the varchar parameter: either CategoryIncome or CategoryOutcome. I would like the Category model class to accept an enum variable - and map it somehow to the string whenever hibernate asks for it.
Is it possible?
Yes, is possible. It should be:
#Enumerated(EnumType.STRING)
#Column(name = "category_type")
private CategoryType categoryType;
The accepted answer is not sufficient for PostgreSQL. I attach the implementation that worked for me:
https://stackoverflow.com/a/64021041/5279996
I had to add
#Column(columnDefinition = "VARCHAR(30)")
to #dcernahoschi solutions to make it work.
#Column(columnDefinition = "VARCHAR(30)")
#Enumerated(EnumType.STRING)
#Column(name = "category_type")
private CategoryType categoryType
Without I got the Exception
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
Related
is it possible using named queries to find all entities based on list containing a certain value.
I have an entity called User
public class User implements Serializable {
private static final long serialVersionUID = -82485348776234092345L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotNull
#Size(min = 5, max = 50)
#Column(name = "email")
private String email;
#NotNull
#Size(min = 5, max = 50)
#Column(name = "password")
private String password;
#Column(name = "creationDate")
#Temporal(TemporalType.TIMESTAMP)
private Date creationDate;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL)
private List<Phone> phoneNumbers;
/* Getters and Setters */
}
I am going to simplify the Phone entity for keeping this post clean:
public class Phone implements Serializable {
private static final long serialVersionUID = -34672347534985L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotNull
#Column(name = "number")
private String number;
#Column(name = "type")
#Enumerated(EnumType.STRING)
private EPhoneType phoneType;
#Column(name = "creationDate")
#Temporal(TemporalType.TIMESTAMP)
private Date creationDate;
#ManyToOne
private User user;
/* Getters and Setters */
}
Now I need to find all the users that have the phone number, lets say: 289647.... and Phone.type = 'MOBILE'
Phone type is an enum.
I am not sure how to acheive this using a named query. With regular native query I can get this done using a JOIN on the tables. Has anyone done something like this with a NamedQuery
First of all, you are probably confusing "named queries" with "JPQL" queries.
A JPA query can be either "native" and "JPQL" - the difference is the query language (SQL or OQL-like; the first is record-oriented, the second is object-oriented).
Both types of queries can be dynamic (built in runtime) or static (aka "named", defined as a static part of the persistence context, just like the entities). The latter can be optimized by creating and storing prepared queries to represent them.
Joining in OQL-like languages (HQL, JPQL) is done in a similar way as in SQL, but they don't represent joining relations (tables) but rather - "object attributes". When joining on an attribute, you don't define any criteria, because these are already part of the entity's definition. On the other hand, joining will create a row per association between entities, so you probably want to use distinct clause (to avoid having User repeated as many times, as a matching Phone appears on the phoneNumbers list).
Probably what you want is:
select u from User u left join u.phoneNumbers n where n.type = :type and n.number = :number
The query above can be used both as named or unnamed variety, to run it you have to provide named parameters type and number: an enum and a string.
I wrote a hql query where i want to update an enum value in database,but i don't know how to update an enum value.This is my model
#Entity
public class ImageInfo implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#Column(name = "ACTIVE")
private Integer active;
#Column(name = "NOTIFICATION_NUM")
private Integer groupNum;
#Column(name = "PUBLISHED_TIME")
#Temporal(TemporalType.TIMESTAMP)
private Date publishedTime;
#Column(name = "POSTED_TIME")
private Timestamp postedTime;
#Enumerated(EnumType.STRING)
private PublishIndicator publishIndicator;
}
you can see there is an enum field named "publishIndicator" . I want to update this field in a hql query.This is my query
session.createQuery("update ImageInfo img set img.active = 1
and img.publishIndicator = :publish where img.active = 0 and
img.publishedTime <:publishedTime ").setParameter("publishedTime",
date).setParameter("publish", PublishIndicator.PUBLISH).executeUpdate();
but i am getting an error
"java.lang.IllegalArgumentException: node to traverse cannot be null!"
i know i am doing something wrong with updating enum valur.How can i solve it?
Use your (fully qualified) PublishIndicator enum.
Instead of PublishIndicator.PUBLISH value, so something like this: (assuming your PublishIndicator enum is in com.image package), Use it as com.image.PublishIndicator.PUBLISH
Many times I'm using #Formula in my entities. But always it was a simple query or stored procedure with parameter which I can take as filed from table. Now I need to user some property from related object. But I see exception when try to get object from DB. Please see an example below
#Entity
#Table(name = "MINISTRY")
public class Ministry {
#Id
#Column(name = "ID")
private Long id;
#Column(name = "NAME")
private String name;
// unnecessary code
}
#Entity
#Table(name = "DEPARTMENT")
public class Department {
#Id
#Column(name = "ID")
private Long id;
#Column(name = "DEP_NAME")
private String departmentName;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "MINISTRY_ID")
private Ministry ministry;
// unnecessary code
}
#Entity
#Table(name = "EMPLOYEE")
public class Employee {
#Id
#Column(name = "ID")
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "DEPARTMENT_ID")
private Department department;
#Formula("test_package.calc_something(department.ministry.id)")
private BigDecimal someMetric;
// unnecessary code
}
How I should use entity prop in #Formula.
I don't want to write something like
select d.ministry.id from Department d ...
If you read the JavaDoc of Formula you will see:
The formula has to be a valid SQL fragment
So you will have to use SQL like:
#Formula("test_package.calc_something("
+ "select DEP.MINISTRY_ID from DEPARTMENT DEP where DEP.ID = DEPARTMENT_ID"
+ ")")
private BigDecimal someMetric;
The only thing that is modified by Hibernate in the fragment before writing it to SQL: It will add the table alias to your columns (as you can't predict that). I mention that, as only a rudimentary SQL parser is used for that, which will insert the alias at wrong positions for more complex fragments.
A remark about performance: The formula is executed for every Department entity that you load, even if you only want to use the attribute for sorting or filtering (just guessing from the name of the attribute) - unless you use #Basic(fetch = FetchType.LAZY) and turn bytecode instrumentation on (or emulate that with FieldHandled).
My class looks like
#Entity
public class Version extends MutableEntity {
#Column(nullable = false)
private String name;
#Column(nullable = false)
#Enumerated(EnumType.STRING)
private VersionType type;
#Column(nullable = false)
#Enumerated(EnumType.STRING)
private VersionStatus status;
#Column(nullable = true)
private DateTime publishedOn;
#Column(nullable = true)
private DateTime retiredOn;
#Column
private Version parentVersion;
I want to have a parentVersion of same type as Version, but my test fails
#Test
public void testVersion() {
Version version = new Version("testVersion", VersionType.MAJOR);
version = crudService.create(version);
assertNotNull(version.getId());
}
and I see error as
Caused by: org.hibernate.MappingException: Could not determine type for: com.myorg.project.versioning.entities.Version, at table: Version, for columns: [org.hibernate.mapping.Column(parentVersion)]
How can I fix this issue?
It is not basic attribute. It is relation because value is other entity. Consequently #ManyToOne annotation should be used:
#ManyToOne
private Version parentVersion;
If bidirectional relationship is needed (parent knowing childrens), that can be done by adding following:
#OneToMany (mappedBy = "parentVersion")
private List<Version> childVersions;
Your are missing some annotations at parentVersion. Hibernate does not know how to map this column in the DB.
Add #JoinColumn to your field and hibernate will use its #Id field.
I use Java Persistence, and I want a web method to return a 'portion' of an Entity class. For example, I have a Customer class that represents a record in Customer table with many fields, but I want to return just few of them. Is it possible to use mapping to do that? Or the only way is to create a new class (maybe a superclass for Customer) that has only fields I want to return? I tried binding, but it didn't work (apparently I did it in a wrong way):
#Entity
#Table(name = "Customer", catalog = "test", schema = "")
#XmlType(name = "Customer")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
#XmlElement
private Integer accountId;
#Basic(optional = false)
#Column(name = "username")
#XmlElement
private String username;
#Basic(optional = false)
#Column(name = "password")
private String password;
I thought that if I don't add #XmlElement annotation to password field, it won't be included into result. However, I got a bunch of "Class has two properties of the same name" errors during deployment.
This is because the default behaviour for XML generation is PUBLIC_MEMBER (http://java.sun.com/javaee/5/docs/api/javax/xml/bind/annotation/XmlAccessorType.html).
Since you are putting the #XmlElement on the fields, it is grabbing both your public getter/setter methods AND any field w/ #XmlElement on it. What you're likely going to want to is set the XmlAccessorType to either FIELD or NONE.
Annotate the class with
#XmlAccessorType(XmlAccessType.NONE)
Then annotate the fields you want to send with
#XmlElement(name="field_name")
There's actually a JAXB issue (that I can't find the reference to right now) that basically says that if you will be reading from XML, you'll want to annotate the setters and not the fields themselves.