I am trying to use PostgreSQL database, running in a docker container, in a Spring Boot project. I was able to connect to the database from IntelliJ, but when I run the app I get the following error:
ERROR: relation "clients" does not exist
I'm getting this error for all my classes, I'm just using the Client class as an example.
Client.java
package com.foober.foober.model;
import com.foober.foober.model.enumeration.Role;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
#Getter
#Setter
#NoArgsConstructor
#Entity(name = "Client")
#Table(name = "clients")
public class Client extends User {
#Column(name = "city", nullable = false, columnDefinition = "TEXT")
private String city;
#Column(name="phone_number", nullable = false, columnDefinition = "TEXT")
private String phoneNumber;
#Column(name="is_activated", nullable = false)
private boolean isActivated;
#Column(name="payment_info", nullable = false, columnDefinition = "TEXT")
private String paymentInfo;
public Client(String username,
String email,
String password,
String firstName,
String lastName,
Role authority,
String image,
String city,
String phoneNumber,
boolean isActivated,
String paymentInfo) {
this.username = username;
this.email = email;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.authority = authority;
this.image = image;
this.city = city;
this.phoneNumber = phoneNumber;
this.isActivated = isActivated;
this.paymentInfo = paymentInfo;
}
}
User.java
package com.foober.foober.model;
import com.foober.foober.model.enumeration.Role;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.Type;
import javax.persistence.*;
import java.util.UUID;
#Getter
#Setter
#NoArgsConstructor
#Entity
#Table(name="users")
#Inheritance(strategy= InheritanceType.JOINED)
public abstract class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Type(type="uuid-char")
protected UUID id;
#Column(name = "username", nullable = false, columnDefinition = "TEXT", unique = true)
protected String username;
#Column(name = "email", nullable = false, columnDefinition = "TEXT", unique = true)
protected String email;
#Column(name = "password", nullable = false, columnDefinition = "TEXT")
protected String password;
#Column(name = "first_name", nullable = false, columnDefinition = "TEXT")
protected String firstName;
#Column(name = "last_name", nullable = false, columnDefinition = "TEXT")
protected String lastName;
#Enumerated(EnumType.STRING)
protected Role authority;
#Column(name = "image", columnDefinition = "TEXT")
protected String image;
}
docker-compose.yaml
version: '2'
services:
db:
container_name: foober
image: 'postgres:14.1-alpine'
volumes:
- data:/data
environment:
- POSTGRES_USER=rootuser
- POSTGRES_PASSWORD=rootpass
- POSTGRES_DB=foober
- PGDATA=/var/lib/postgresql/data/pgdata
ports:
- 5432:5432
volumes:
data: {}
application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/foober
spring.datasource.username=rootuser
spring.datasource.password=rootpass
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.defer-datasource-initialization=true
spring.sql.init.mode=always
Related
package com.srikanth.oncode.entity;
import java.io.Serializable;
import org.hibernate.annotations.ColumnTransformer;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
#Entity
public class Employee implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private int id;
#ColumnTransformer(forColumn = "name",
read = "pgp_sym_decrypt(name, 'mykey}')",
write = "pgp_sym_encrypt(?, 'mykey}')")
#Column(name = "name",columnDefinition = "bytea")
String name;
#ColumnTransformer(forColumn = "emailId",
read = "pgp_sym_decrypt(email_id,'mykey}')",
write = "pgp_sym_encrypt(?,'mykey}')")
#Column(name = "emailId",columnDefinition = "bytea")
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Employee(String name, String email) {
super();
this.name = name;
this.email = email;
}
public Employee() {
super();
}
}
```......................................
here i have hardcoded secret key with -> mykey but i want it to be externalized from application.properties.
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private int id;
#ColumnTransformer(forColumn = "name",
read = "pgp_sym_decrypt(name, '${mykey}')",
write = "pgp_sym_encrypt(?, '${mykey}')")
#Column(name = "name",columnDefinition = "bytea")
String name;
#ColumnTransformer(forColumn = "emailId",
read = "pgp_sym_decrypt(email_id,'${mykey}')",
write = "pgp_sym_encrypt(?,'${mykey}')")
#Column(name = "emailId",columnDefinition = "bytea")
private String email;
......................
i have tried in this way to load key from application.properties but it not working.
Just having a look at REST Data with Panache wondering if it is possible to exclude some entity fields from beeing exposed by the rest resource, as we need the generated REST resources only for read access pattern.
However, in the docs https://quarkus.io/guides/rest-data-panache I did not find a way to do it.
Looks like it is using Jackson for JSON, so #JsonIgnore should work for you.
#JSonIgnore can be used at the field level, or you can add it on the Getter or Setter if you want only specific parts to be ignored.
#Entity
#Table(name = "order_item")
public class OrderItem extends PanacheEntityBase {
#Id
#GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
#GeneratedValue(generator = "uuid")
#Column(name = "id", length = 36, nullable = false)
#Getter
#Setter
private String id;
#Getter
#Setter
#ManyToOne(targetEntity = Order.class)
#JsonIgnore
#JoinColumn(name = "order_id")
private Order orderId;
#Getter
#Setter
#JsonIgnore
#ManyToOne(targetEntity = Item.class)
#JoinColumn(name = "item_id")
private Item itemId;
#Getter
#Setter
#Column(name = "quantity", nullable = false)
private Integer quantity;
#Getter
#Setter
#Column(name = "price_total", nullable = false)
private Double priceTotal;
#Getter
#Setter
#Column(name = "note", columnDefinition = "text")
private String note;
}
Or you can use #JsonIgnoreProperties at the top level of the class:
#Entity
#JsonIgnoreProperties(value = { "creator", "created" }, allowSetters = false, allowGetters = true)
public class UpdateUserDeviceTokenRequest extends PanacheEntity {
#NotNull
#NotEmpty
#NotBlank
public String userDeviceToken;
#ManyToOne()
#JoinColumn(name = "creatorUser", insertable = true, updatable = false)
public AppUser creator;
#Column(insertable = true, updatable = false)
public LocalDateTime created;
public UpdateUserDeviceTokenRequest() {
}
#PrePersist
void onCreate() {
this.created = LocalDateTime.now();
}
public UpdateUserDeviceTokenRequest(#NotNull #NotEmpty #NotBlank String userDeviceToken) {
super();
this.userDeviceToken = userDeviceToken;
}
}
Please see https://github.com/quarkusio/quarkus/issues/10339 for possible issue that might arise
org.postgresql.util.PSQLException: ERROR: insert or update on table "party_custom_fields" violates foreign key constraint "fk21oqkpi7046skme7jce06fxdu"
Below error could help, what need to be done on the code, I have tried few reference, but not helpful.
Detail: Key (custom_field_value)=(11) is not present in table "custom_field_value"
Above is my error while saving.
Party is the class which will have custom fields and it's data
import lombok.Data;
import javax.persistence.*;
import java.util.HashMap;
import java.util.Map;
#Entity
#Data
#Table(name = "party")
public class Party {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
#Column(name = "last_name")
private String lastName;
private String email;
private String gender;
#OneToMany(cascade = CascadeType.ALL)
#JoinTable(name = "party_custom_fields",
joinColumns = {#JoinColumn(name = "custom_field")},
inverseJoinColumns = {#JoinColumn(name = "custom_field_value")})
#MapKeyColumn(name = "custom_field_key")
private Map<Long, CustomFieldValue> customField = new HashMap<>();
public Party() {
}
public Party(String name) {
this.name = name;
}
}
Custom fields value model
package org.aeq.multitenant.model;
import lombok.Data;
import javax.persistence.*;
#Data
#Entity
#Table(name = "custom_field_value")
public class CustomFieldValue {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String value;
}
Custom fields model which hold what are the custom fields for the tables
package org.aeq.multitenant.model;
import lombok.Data;
import org.aeq.multitenant.enums.Tables;
import javax.persistence.*;
#Data
#Entity
#Table(name = "custom_field")
public class CustomField {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String type;
private boolean optional;
#Enumerated(EnumType.STRING)
#Column(name = "table_name")
private Tables tableName;
}
Controller function to save
Map<Long, CustomFieldValue> cfMap = new HashMap<>();
for (CustomField cf : customFields) {
if (!partyData.containsKey(cf.getName())) {
return new ApiResult<>(false, "Please provide " + cf.getName() + " custom field of party");
} else {
CustomFieldValue cfv = new CustomFieldValue();
cfv.setValue(partyData.get(cf.getName()).trim());
cfv = customFieldValueRepository.save(cfv);
cfMap.put(cf.getId(), cfv);
}
}
Party party = new Party();
party.setName(partyData.get("name"));
party.setEmail(partyData.get("email").trim());
party.setGender(partyData.get("gender").trim());
party.setLastName(partyData.get("last_name").trim());
party.setCustomField(cfMap);
party = partyRepository.save(party);
please review my code and let me where I am going wrong
If a column has a foreign key constraint, then any entry to that column should be present in the reference table given. If not, then this exception will be thrown.
I am having an issue in setting up a many to many relationship in my entities. And I don't understand why
failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: cardgame.bean.User.card in cardgame.bean.Card.users
My Entities:
#MappedSuperclass
#Data
public class BaseEntity implements Serializable {
#Id
#Column(name = "id", nullable = false, unique = true)
private String id;
public BaseEntity() {
this.id = UUID.randomUUID().toString();
}
}
My user emtity:
#Data
#Entity
#Table(name = "users")
public class User extends BaseEntity {
#Column(name = "username", nullable = false, unique = true)
private String username;
#Column(name = "uuid", nullable = false)
private String uuid;
#Column(name = "email", nullable = false, unique = true)
private String email;
#OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Card> cards;
#Column(name = "isActive", nullable = false)
private boolean isActive;
}
My card entity:
#Data
#Entity
#Table(name = "cards")
public class Card extends BaseEntity {
#OneToMany(mappedBy = "card")
private List<User> users;
#Column(name = "strength", nullable = false)
private int strength;
#Column(name = "isActive", nullable = false)
private boolean isActive;
}
The users and cards tables have a many-to-many relationship via user_card table:
#Data
#Entity
#Table(name = "user_card")
public class UserCard implements Serializable {
#Id
#ManyToOne
#JoinColumn(name = "user_id", nullable = false)
private User user;
#Id
#ManyToOne
#JoinColumn(name = "card_id", nullable = false)
private Card card;
#Column(name = "cardCount", nullable = false)
private int cardCount;
}
What am i doing incorrect. Please help me
I am currently trying to display information requested via JPA 2.0 (eclipselink). I am using glassfish 3.0.1 and netbeans 6.9.1 as IDE. My persistence entities are created under netbeans option "create entity classes from database". My shcema is designed with workbench mysql, and my server is of course mysql. I really cant figure out what creates this #JoinColumns error.
javax.servlet.ServletException: Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [myprojectPU] failed.
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The #JoinColumns on the annotated element [field userInfo] from the entity class [class com.myproject.jpa.UserId] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn.
This part randomly swaps from [field userInfo] from the entity class [class com.myproject.jpa.UserId] to [field userIdList] from the entity class [class com.myproject.jpa.Cell]. So both classes probably have the same issue.
Here are my classes:
#Entity
#XmlRootElement
#Table(name = "user_id", catalog = "workitout", schema = "")
public class UserId implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected UserIdPK userIdPK;
#Basic(optional = false)
#Column(name = "email", nullable = false, length = 45)
private String email;
#Basic(optional = false)
#Column(name = "password", nullable = false, length = 45)
private String password;
#ManyToMany(mappedBy = "userIdList")
private List<Cell> cellList;
#JoinColumn(name = "USER_INFO_id_info", referencedColumnName = "id_info", nullable = false, insertable = false, updatable = false)
#ManyToOne(optional = false)
private UserInfo userInfo;
...
}
#Entity
#XmlRootElement
#Table(name = "user_info", catalog = "workitout", schema = "")
public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected UserInfoPK userInfoPK;
#Basic(optional = false)
#Column(name = "fullName", nullable = false, length = 45)
private String fullName;
#Basic(optional = false)
#Column(name = "city", nullable = false, length = 45)
private String city;
#Basic(optional = false)
#Column(name = "gender", nullable = false, length = 10)
private String gender;
#Basic(optional = false)
#Column(name = "isCoach", nullable = false)
private boolean isCoach;
#Column(name = "age")
private Integer age;
#Column(name = "description", length = 200)
private String description;
#Column(name = "linkImage", length = 45)
private String linkImage;
#Column(name = "friendList", length = 500)
private String friendList;
#Column(name = "coachList", length = 500)
private String coachList;
#JoinColumn(name = "USER_SPORT_id_sport", referencedColumnName = "id_sport", nullable = false, insertable = false, updatable = false)
#ManyToOne(optional = false)
private UserSport userSport;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userInfo")
private List<UserId> userIdList;
...
}
*The first error was solved, but the [field userIdList] from the entity class [class com.myproject.jpa.Cell]. remains. Ive added the code of my cell table:
import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
#Entity
#XmlRootElement
#Table(name = "cell", catalog = "workitout", schema = "")
#NamedQueries({
#NamedQuery(name = "Cell.findAll", query = "SELECT c FROM Cell c"),
#NamedQuery(name = "Cell.findByIdCell", query = "SELECT c FROM Cell c WHERE c.idCell = :idCell"),
#NamedQuery(name = "Cell.findByName", query = "SELECT c FROM Cell c WHERE c.name = :name")})
public class Cell implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#Column(name = "id_cell", nullable = false)
private Integer idCell;
#Basic(optional = false)
#Column(name = "name", nullable = false, length = 45)
private String name;
#ManyToMany
#JoinTable(name = "user_id_has_cell", joinColumns = {
#JoinColumn(name = "cell_id_cell", referencedColumnName = "id_cell", nullable = false)}, inverseJoinColumns = {
#JoinColumn(name = "USER_ID_id", referencedColumnName = "id", nullable = false),
#JoinColumn(name = "USER_INFO_id_info", referencedColumnName = "id_info", nullable = false, insertable = false, updatable = false),
#JoinColumn(name = "USER_SPORT_id_sport", referencedColumnName = "id_sport", nullable = false, insertable = false, updatable = false)
})
private List<UserId> userIdList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "cell")
private List<WorkoutSession> workoutSessionList;
public Cell() {
}
public Cell(Integer idCell) {
this.idCell = idCell;
}
public Cell(Integer idCell, String name) {
this.idCell = idCell;
this.name = name;
}
public Integer getIdCell() {
return idCell;
}
public void setIdCell(Integer idCell) {
this.idCell = idCell;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<UserId> getUserIdList() {
return userIdList;
}
public void setUserIdList(List<UserId> userIdList) {
this.userIdList = userIdList;
}
public List<WorkoutSession> getWorkoutSessionList() {
return workoutSessionList;
}
public void setWorkoutSessionList(List<WorkoutSession> workoutSessionList) {
this.workoutSessionList = workoutSessionList;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idCell != null ? idCell.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Cell)) {
return false;
}
Cell other = (Cell) object;
if ((this.idCell == null && other.idCell != null) || (this.idCell != null && !this.idCell.equals(other.idCell))) {
return false;
}
return true;
}
Error message describes the problem pretty clearly - UserInfo has a composite key, therefore you need to specify several #JoinColumns, one column for each field of the composite key:
#JoinColumns({
#JoinColumn(...),
#JoinColumn(...)
})
#ManyToOne(optional = false)
private UserInfo userInfo;
From the error message I would try to add the following to your class UserId:
#JoinColumn(name = "USER_INFO_uSERSPORTidsport", referencedColumnName = "uSERSPORTidsport", nullable = false, insertable = false, updatable = false)
#ManyToOne(optional = false)
private UserSport usersport;