I am trying to create a Privilege class with Annotations whose Primary Key is a String. I will assign them manually while inserting. Therefore no need for hibernate to generate a value for it. I'm trying to do something like that:
#Id
#GeneratedValue(generator = "assigned")
#Column(name = "ROLE_NAME", nullable = false)
private String roleName;
But it throws that exception:
Caused by: org.hibernate.AnnotationException: Unknown Id.generator: assigned
How can I configure a String primary key with annotations?
Since the roleName is not auto-generated, you should simply not annotate it with #GeneratedValue:
#Id
#Column(name = "ROLE_NAME", nullable = false)
private String roleName;
#Id
#Column(name = "USER_ID",unique=true,columnDefinition="VARCHAR(64)")
private String userId;
This worked for me by representing the columnDefinition type with column annotation during the save or update.
Just use the #Id annotation which lets you define which property is the identifier of your entity. You don't need to use the #GeneratedValue annotation because I don't think you want hibernate to generate this property for you.
Even in the XML configuration based approach its an optional tag and can be skipped.
you can enter this way, suppose position is primary key of that Salary entity,
#Id
#Column (name = "POSITION", nullable = false)
private String position;
then, it will work
Related
Hello i have an entity that have an inner id autogenerated by db and the uuid used as the actual id in the rest of the project. Immagine something like this:
#Entity
#Data
public class Task {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(nullable = false)
private Long innerId;
#Column(nullable = false, unique = true)
#Type(type="uuid-char")
private UUID uuid;
private String name;
}
i would like to set the uuid as the ID for javers, is there any way of doing so ? becaus javers "detects" the "persistence id annotation" and establish that as its own id.
I tried adding to the uuid column the annotation
#org.javers.core.metamodel.annotation.Id
but in this case javers creates a composite id made of innerId and uuid, and this doesn't works for me
I have 2 tables (User and Feed) linked by a foreign key. Following that, I am using Spring Boot and Hibernate to make a query to just print out all the values in Feed table. But when it comes to the foreign key and its value, my Entity seems to be going wrong where it creates a new column on the fly when I already have a column for the foreign key.
Can I please know what I am doing wrong? New to this JPA setup. Confused as to whether I should even create my schema first or let JPA just handle things according to my Entity setups. Clearly I am missing something vital this but just can't place a finger on it. Please assist.
Question is how do I map to the foreign key? As in map Feed table's foreign key 'owner_name' to User table's 'username' on the Entity?
Table structures
Entities
User Entity
#Entity
public class User {
#Id
#Column(name = "username")
public String username;
#Column(name = "email")
public String email;
#Column(name = "password")
public String password;
#Basic
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "created_at")
private Date createdAt;
#Column(name = "online_status")
private long onlineStatus;
#Column(name = "account_status")
private long accountStatus;
//updated this based on Gopi's suggestion
#OneToMany(mappedBy = "ownerName")
private List<Feed> feeds;
}
Feed Entity
#Entity
public class Feed {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "feed_id")
private long feedId;
#Column(name = "title")
private String title;
#Basic
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "created_at")
private Date createdAt;
#Basic
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updated_at")
private Date updatedAt;
#ManyToOne
#JoinColumn(name = "username")
// #Column(name = "owner_name")
private User ownerName;
}
My query to just get all the Feed data where I do get all data less the value for foreign key which comes out as null. (expecting to get the foreign key value instead).
My controller is calling this method where I get all results less the foreign key value.
public interface FeedRepository extends JpaRepository<Feed, Long> {
#Query("select f from Feed as f order by f.createdAt desc")
List<Feed> getCurrentFeeds();
}
Test values inside the tables.
User table data
Feed table data
If I run my current code, I end up with an additional column on the fly as follows which I do not want as mentioned above.
Hi this is not surprising, you have specified as a name attribute to the #JoinColumn the column that is actualy referenced. You need to specify the foreign key column in the Feed table which is the "owner_name". The correct complete definition of the #JoinColumn would be:
#JoinColumn(name="owner_name",referencedcolumn = "username")
private User ownerName;
Where you don't actualy need to define the referencedcolumn, but I have defined it for completion so that you understand what is what.
I am having one hibernate pojo class which has 3 fields specified in #UniqueConstraint (unique together) where one of these 3 fields is nullable=true.
When I try to update entry with session.update(pojo) it updates all the entries in database which matches 2 fields (which are not nullable), so does hibernate avoid nullable fields while querying? or there is something what I should know about it?
Edit: Added class
#Entity
#Table (name = "details",
uniqueConstraints = {#UniqueConstraint(columnNames = {"service_id", "billing_item_id", "service_type_id"}, name="UK_name_it")}
)
public class Detail implements Serializable {
#ManyToOne
#JoinColumn(name = "service_id")
#ForeignKey(name = "FK_name2")
#Id
private Service service;
#ManyToOne
#JoinColumn(name="billing_item_id")
#ForeignKey(name = "FK_name3")
#Id
private BillingItem billingItem;
#ManyToOne
#JoinColumn(name="currency_id")
#ForeignKey(name = "FK_name4")
private Currency currency;
#ManyToOne
#JoinColumn(name="service_type_id")
#ForeignKey(name = "FK_name5")
private ServiceType serviceType;
#Column(name = "completed", nullable = false)
private boolean completed;
}
There doesn't seem to be any option like that to have a nullable field in composite key, so I had to end up by adding a integer autoincrement primary key to the table, and keeping service, billingItem and serviceType fields in #UniqueConstraint.
There is another option I could adopt, which is possible in certain scenarios, by adding a serviceType which is considered as All entry (basically when serviceType is null it applies to all the serviceTypes.) and instead of using null for serviceType point to this entry, this way we can have PK and no need to make serviceType a nullable field.
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 "
In a legacy database, I have three tables: Users, Workgroups, and UsersWorkgroup. UsersWorkgroup stores what role a user has in a workgroup.
Here are the relevant code snippets:
#Entity
#Table(name = "users_workgroup")
public class UsersWorkgroup implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected UsersWorkgroupPK usersWorkgroupPK;
#JoinColumn(name = "idworkgroup", referencedColumnName = "idworkgroup")
#ManyToOne(optional = false)
private Workgroup workgroup;
#JoinColumn(name = "user_name", referencedColumnName = "user_name")
#ManyToOne(optional = false)
private Users users;
#Column(name = "role")
private Integer role;
#Embeddable
public class UsersWorkgroupPK implements Serializable {
#Basic(optional = false)
#Column(name = "idworkgroup", insertable=false, updatable=false)
private int idworkgroup;
#Basic(optional = false)
#Column(name = "user_name", insertable=false, updatable=false)
private String userName;
#Entity
#Table(name = "workgroup")
public class Workgroup implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idworkgroup")
private Integer idworkgroup;
#Column(name = "name")
private String name;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "idworkgroup")
private Collection<UsersWorkgroup> usersWorkgroupCollection;
And of course, problem is, it doesn't work.
Currently I get this exception:
Exception Description: An incompatible
mapping has been encountered between
[class entity.Workgroup] and [class
entity.UsersWorkgroup]. This usually
occurs when the cardinality of a
mapping does not correspond with the
cardinality of its backpointer.
Which I don't understand since OneToMany should match ManyToOne... Or is it a ManyToMany relationship? If I switch to #ManyToMany, I get this:
Exception Description: The target
entity of the relationship attribute
[workgroup] on the class [class
com.ericsson.rsg.ejb.entity.UsersWorkgroup]
cannot be determined. When not using
generics, ensure the target entity is
defined on the relationship mapping.
I'm trying to understand compound keys (embedded), but all the examples I could find have only simple columns that are not foreign keys (but that's the whole point of a compound key, isn't it?). Can the UsersWorkgroup table secretly be a join table?
Should I declare the PK class as a strict POJO class? Or should I put the #JoinColumn annotations in the PK class? How do I refer to the columns within the compound key from another table? Should I initialize the PK object in the refering class constructor, or is it not necessary?
I feel stuck completely.
First of all, I think your relation is a Many To Many, as a user can be in many groups, and a group can have many users (or I would assume so).
Second, as far as I know you have to reference both id_workgroup and user_name as JoinColumns, because they are part of the PK and a unit, so both should be referenced.
Also, I see the "equals" and "hashCode" methods missing from your embedded PK, as well as the getters/setters. I believe they are mandatory.
Your mapping looks fine except for mappedBy - it should be a property name, not a column name:
#OneToMany(cascade = CascadeType.ALL, mappedBy = "workgroup")
private Collection<UsersWorkgroup> usersWorkgroupCollection;