[PersistenceException: Error getting sequence nextval] - java

i am getting this error while trying to save data into model in db.
#Entity
public class User extends Model {
#Required
public String name;
#Email
public String email;
#Required #MaxLength(value=10)
public String username;
#Required #MinLength(value=4)
public String password;
#Id
public int id;
}
this is my Class.
this is the error while i am trying to save the model into db.
i will appreciate any effort for help! many thanks.
EDIT: table structure is here

I think with ebean you have to physically name and annotate your id. You may also have to tell it the name of the backing sequencer as well (I dont remember). This shows how to do it.

This worked for me:
#Entity
#Table(name = "table", schema = "schema")
public class Bean extends Model{
#Id
#Column(name = "idcolumn")
#SequenceGenerator(name="gen", sequenceName="schema.table_idcolumn_seq",allocationSize=1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "gen")
private int id;
}
When using the SequenceGenerator, please mind this bug in Hibernate: https://hibernate.atlassian.net/browse/HHH-7232
It forces you to write the schema directly into the sequenceName instead of using the schema field in the SequenceGenerator annotation.

This worked for me on class annotation:
#SequenceGenerator(name = "SEQUENCE_NAME", sequenceName = "PST_BUSINESS.S_BUSINESS_DOMAIN")
#Entity
#Table(name = "TB_BUSINESS_DOMAIN", schema = "PST_BUSINESS")
public class PstBusinessDomain extends PstAbstractBaseMappedEntity {
As Leo said, this strategy works for annotation in the field and also in the class.

Related

#GeneratedValue seemingly does not auto-generate when the Entity is being added using a POST Request

This is my Entity class (shortened for obvious reasons):
Song.java:
#Entity
#Table(name = "songs", schema = "dbo")
public class Song {
#Id
#GeneratedValue
#Column(name = "song_id")
private Integer songId;
// other properties and getter setters not needed for the question
}
Here's my controller (again, shortened for obvious reasons):
SongsController.java:
#RestController
#RequestMapping("/songs")
public class SongsController {
#Autowired
private SongRepository songs;
//GET, DELETE and PUT mappings not neeeded for the question
//POST: adds a new song to the repository
#PostMapping("/add")
public void addSong(#RequestBody(required = true) Song song) throws DuplicateItemException {
if(songs.existsById(song.getSongId())) {
throw new DuplicateItemException(); //simplest possible custom exception handler imaginable
}
songs.save(song);
}
}
Here's my POST request from POSTMAN:
{
"songName": "Song3",
"songDuration": "490"
}
Here's what the function receives:
songName: "Song3"
songDuration: "490"
songId: null
The Exception that gets thrown is "songId cannot be null". How do I fix this?
My database is PostgreSQL (12.10.1).
You need to explicitly add strategy to generated value. Otherwise it will not work. Try this:
#GeneratedValue(strategy = GenerationType.AUTO)
Your #GeneratedValue is missing how to generate the value! Given that you're using PostgreSQL and such RDMS allows the creation of database sequences, I'll suggest the following configuration ... In your Song class, you need to add the #SequenceGenerator annotation and make the following changes:
#Entity
#Table(name = "songs", schema = "dbo")
#SequenceGenerator(
name = "<AnyNameThatFitsYou>",
sequenceName = "<TheNameOfYourDatabaseSequence>",
initialValue = <DatabaseSeqInitVal>,
allocationSize = <HowManyOfTheseValuesShouldBeAllocatedInJPAMemoryForFastAccess>
)
public class Song {
#Id
#GeneratedValue(
generator = "<TheNameYouGiveToTheSequenceGenerator>",
strategy = GenerationType.SEQUENCE
)
#Column(name = "song_id")
private Integer songId;
// other properties and getter setters not needed for the question
}
That should be all ...

Java entity modeling with table that relates to several others

I have a doubt about how the modeling of my entity would be. Come on, I have a table in the database that serves to save documents from my system, this table has the columns id, fk_id (element foreign key), fk_table (entity name) and file_name (stores the name of my file) .
I did a lot of research before posting my question here, but I didn't find anything related to it, what would my entities, user, patient and doctor?
DB:
id
fk_id
fk_table
file_name
1
21
user
test1.jpg
2
32
doctor
test2.pdf
3
61
user
test10.pdf
4
100
patient
test5.jpg
Class:
public class User{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String LastName;
// What would a one-to-many relationship look like?
}
public class patient{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
// What would a one-to-many relationship look like?
}
You can use #Where. But be aware that #Where is a Hibernate annotation. It's not in the JPA standard.
For example in the User entity: (I assume that your table is mapped to an entity called Document)
#Where( clause = "fk_table = 'user'")
#JoinColumn(name = "fk_id")
#OneToMany
private List<Document> documents = new ArrayList<>( );
The following is based only on standard JPA annotations. The idea is to create an inheritance hierarchy for the documents table. The base is:
#Entity
#Table(name = "XX_DOCUMENT")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "fk_table")
public abstract class BaseDocument {
#Id
#GeneratedValue(strategy=SEQUENCE)
private Long id;
#Column(name = "file_name")
private String fileName;
}
Here we define that all entities extending this will go to the same table, with the fk_table column to discriminate. The entities extending it are defined as follows:
#Entity
#DiscriminatorValue("doctor")
public class DoctorDocument extends BaseDocument {
#ManyToOne
#JoinColumn(name = "fk_id")
private Doctor doctor;
}
#Entity
#DiscriminatorValue("patient")
public class PatientDocument extends BaseDocument {
#ManyToOne
#JoinColumn(name = "fk_id")
private Patient patient;
}
// and so on
The interesting thing is that we are reusing the column fk_id to point to the right table. From a small experiment, Hibernate seems to not have problems with it. I would suggest that you manage the DB creation another way just to be safe.
The Doctor, Patient etc need not have a common base class, e.g.:
#Entity
#Table(name = "XX_DOCTOR")
public class Doctor {
#Id
#GeneratedValue(strategy=SEQUENCE)
private Long id;
#OneToMany(mappedBy = "doctor")
private Collection<DoctorDocument> documents = new ArrayList<>();
// any doctor-specific fields
}
#Entity
#Table(name = "XX_PATIENT")
public class Patient {
#Id
#GeneratedValue(strategy=SEQUENCE)
private Long id;
#OneToMany(mappedBy = "patient")
private Collection<PatientDocument> documents = new ArrayList<>();
// any patient-specific fields
}
// and so on
You can read a (doctor, patient, ...)'s documents from the relevant collection. You can even query BaseDocument instances based on any criteria.
You can even go ahead and do more fabcy stuff with the Java code. E.g. define an interface HasDocuments:
public interface HasDocuments<D extends BaseDocument> {
Collection<D> getDocuments();
}
Doctor, Patient, ..., implements this, so they can all be treated the same way.

#Column and #Enumerated doesn't work in embeded entity

I have main entity:
#Entity
#Table(name = "partners")
public class Partner {
#ElementCollection
#CollectionTable(
name = "external_login",
joinColumns = #JoinColumn(name = "partner_id")
)
private List<ExternalLogin> externalLogins;
...
}
And ExternalLogin is embeded entity
#Embeddable
public class ExternalLogin {
#Column(name = "type")
#Enumerated(value = EnumType.STRING)
private ExternalLoginType type;
#Column(name = "login")
private String login;
#Column(name = "password_value")
private String passwordValue;
}
public enum ExternalLoginType {
ABC;
}
#Column and #Enumerated not works in ExternalLogin entity.
For example in query will be external_login.passwordValue instead of external_login.password_value.
#Enumerated(value = EnumType.STRING) doesn't work too. Hibernate is trying to get int value of filed instead string.
Can anyone help me?
You misuse annotation #Embeddable. See description in oracle docs https://docs.oracle.com/javaee/6/api/javax/persistence/Embeddable.html
Defines a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity. Each of the persistent properties or fields of the embedded object is mapped to the database table for the entit
#Embeddable annotation makes sense only for singular assotiation fields. Annotating list fields as #Embeddable is wrong.
Just replace
#Embeddable
public class ExternalLogin {
to
#Entity
public class ExternalLogin {
I had exactly the same issue just now.
The solution for me ended up being adding
#Access(FIELD)
To the Embeddable object.

Modeling UUID in Hibernate entity against MySQL

I have a very similar question to this one, however my question is even more basic than that one and so I don't feel like its a dupe...(we'll see what SO thinks). And if it is a dupe of another question, please point out to me (perhaps in a comment) how the accepted answer completely answers/addresses my issue (I don't think it does!).
I have a Java/JPA/Hibernate #Entity class that needs to have a UUID field:
#Canonical
#MappedSuperclass
public abstract class BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private UUID refId;
// Getters/setters/ctors/etc.
}
#Entity(name = "accounts")
#AttributeOverrides({
#AttributeOverride(name = "id", column=#Column(name="account_id")),
#AttributeOverride(name = "refId", column=#Column(name="account_ref_id"))
})
public class Account extends BaseEntity {
// blah whatever
}
That is, I need to be working with UUIDs at the app layer. However the database here is MySQL, and the overwhelming recommendations for representing UUIDs in MySQL seems to be to represent them as a VARCHAR(36), so that's what I have.
At runtime I'm getting the following exception:
Caused by: org.hibernate.HibernateException: Wrong column type in my_db.accounts for column account_ref_id. Found: varchar, expected: binary(255)
at org.hibernate.mapping.Table.validateColumns(Table.java:373)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1338)
<rest of stack trace omitted for brevity>
So clearly, the database is presenting a VARCHAR(36), but Hibernate seems to be defaulting to expect a binary(255).
I honestly don't care what the UUID gets stored as in the DB. It could be VARCHAR, it could be TEXT, it could be BLOB...it could be a toaster oven for all I care! But the essential requirement here is that the data model (the entity class) use UUIDs.
What's the fix here? If I have to change the column type in the DB, what do I change the type to? If I have to change/modify the UUID field in the entity, what else do I need to annotate it with?
For me the fix required changes to both DB schema as well as the entity (Java) code.
First I changed my CREATE TABLE statement to use BINARY(255) instead of VARCHAR(36):
CREATE TABLE IF NOT EXISTS accounts (
# lots of fields...
account_ref_id BINARY(255) NOT NULL,
# ...lots of other fields
);
Next I added #Type(type="uuid-binary") to my field declaration in the entity:
#Canonical
#MappedSuperclass
public abstract class BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Type(type="uuid-binary")
private UUID refId;
// Getters/setters/ctors/etc.
}
#Entity(name = "accounts")
#AttributeOverrides({
#AttributeOverride(name = "id", column=#Column(name="account_id")),
#AttributeOverride(name = "refId", column=#Column(name="account_ref_id"))
})
public class Account extends BaseEntity {
// blah whatever
}
This works beautifully for me.
Try it like this:
public class BaseEntity{
#Column(nullable = false)
private String uuid;
public BaseEntity(){
setUuid(UUID.randomUUID().toString());
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
#PrePersist
public void prePersist(){
if(null == getUuid())
setUuid(UUID.randomUUID().toString());
}
....
Column definition:
uuid varchar(255) DEFAULT NULL
When generating UUID use toString method:
entity.setUuid(UUID.randomUUID().toString())

PSQLException: ERROR: syntax error at or near

I have what I thought was a straight forward relation in JPA. Looks like this. CompanyGroup:
#Entity
#Table
public class CompanyGroup implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
#Column(name = "name")
private String name;
#JoinColumn(name = "companies")
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Company> companies;
}
Company:
#Entity
#Table
public class Company implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "name")
private String name;
#JoinColumn(name = "users")
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<User> users;
#Id
#GeneratedValue
private Long id;
}
User:
#Entity
#Table
public class User {
#Column(name = "firstName")
private String firstName;
#Column(name = "lastName")
private String lastName;
#Column(name = "email")
private String email;
#Id
#GeneratedValue
private Long id;
}
I have omitted setters, getters, etc.
This is not working. I'm trying to save a CompanyGroup(Has 2 companies, each company has 2 users, all entities are unique) to a fully empty database.
I persist this using Spring-Data, accessed in a service like this:
#Service
public class ConcreteCompanyGroupService implements CompanyGroupService {
#Autowired
private CompanyGroupRepository repository;
#Transactional
#Override
public void save(CompanyGroup group) {
repository.save(Collections.singleton(group));
}
}
When I try to call this method I receive this:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "User"
Position: 13
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2458)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2158)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:291)
Hopefully I have done something stupid that someone can find quickly. I don't know how to solve this.
EDIT:
The driver in my pom.xml:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1211</version>
</dependency>
Your entity maps across to a table name that is an SQL reserved keyword (User). Sadly for you, your chosen JPA provider does not automatically quote the table name identifier, and so you get exceptions when referring to the table.
Solution is either to quote the table name yourself in the #Table annotation, or change the table name to not be a reserved keyword. Alternatively use a JPA provider that auto-quotes such reserved keywords for you (e.g DataNucleus)
Solution 1: As Pascal mentioned, you have to escape the table name with backslash like:
#Entity
#Table(name="\"User\"")
public class User {
...
}
Solution 2: Rename your table's anme with another name (Users)
#Entity
#Table(name="Users")
public class User {
...
}
Solution 3: Add a suffix to the table's name:
#Entity
#Table(name="APP_User")
public class User {
...
}
Solution 4: Change the entity name, e.g. ApplicationUser
#Entity
public class ApplicationUser {
...
}
The reason
PostgreSQL as some reserved SQL Key Words. For example: ABORT, ALL, ARRAY, CACHE, CUBE, USER, ... Those tokens are in the SQL standard or specific to PostgreSQL
Use the #Table annotation or change your class name from User to something else as User is a reserved keyword in sql.

Categories

Resources