So, i create Entity in my DB from CommandLineRunner, everything okay.
Then i create some controller one of them give me next Exception, when i going to update my Entity ->
***java.sql.SQLIntegrityConstraintViolationException: Column 'name' cannot be null***
Controller
#PostMapping ("/update")
public String update (Instructor instructor) {
instructorService.updateInstructor(instructor);
return "redirect:/instructors/index";
}
Entity
#Entity
#Table (name = "Instructor")
public class Instructor {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
#Column (name = "instructor_id", nullable = false)
private Long instructorId;
#Basic
#Column (name = "name", nullable = false, length = 45)
private String firstName;
#Basic
#Column (name = "lastName", nullable = false, length = 45)
private String lastName;
#Basic
#Column (name = "summary", nullable = false, length = 45)
private String instructorSummary;
#OneToMany (mappedBy = "instructor", fetch = FetchType.LAZY)
private Set <Course> courses = new HashSet<>();
#OneToOne (cascade = CascadeType.REMOVE)
#JoinColumn (name = "user_id", referencedColumnName = "user_id", nullable = false)
private User user;
When i delete (nullable=false) everything work by Entity does not appear in DB
Instructor Service
Instructor updateInstructor (Instructor instructor);
InstructorImpl
#Override
public Instructor updateInstructor(Instructor instructor) {
return instructorDao.save(instructor);
}
DaoClass only extend JpaRepository
Update: here are the logs
Hibernate: update instructor set name=?, summary=?, last_name=?,
user_id=? where instructor_id=? 2023-01-13T14:41:40.545+02:00 WARN
4176 --- [nio-8071-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper :
SQL Error: 1048, SQLState: 23000 2023-01-13T14:41:40.545+02:00 ERROR
4176 --- [nio-8071-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper :
Column 'name' cannot be null 2023-01-13T14:41:40.551+02:00 ERROR 4176
--- [nio-8071-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path
[] threw exception [Request processing failed:
org.springframework.dao.DataIntegrityViolationException: could not
execute statement; SQL [n/a]; constraint [null]] with root cause
Related
I am creating a database of items and have been trying to assign multiple database entities to a single item however I am struggling to get past an error I keep having. I am unsure what I am doing wrong can someone help?
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FKKPIB0GWXM6UFS3SJJ2NCI64AR: PUBLIC.FEATURES FOREIGN KEY(ITEM_ID) REFERENCES PUBLIC.ITEM(ITEM_ID) (CAST(1020 AS BIGINT))"; SQL statement: INSERT INTO FEATURES(FEATURE_ID, ITEM_ID) VALUES(101, 1020), (102,1021), (103,1021), (104,1021)
Item.java
#Entity
#Table(name="item")
public class Item {
#Id
#Column(name = "item_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
#Enumerated(EnumType.STRING)
private ItemType itemtype;
private int weight;
private int recovers;
private int priority;
private String desc;
#OneToMany(mappedBy = "item")
private List<Feature> features;
}
Feature.java
#Entity
#Table(name = "features")
public class Feature {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long feature_id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "item_id", insertable = false, updatable = false)
#JsonIgnore
private Item item;
}
data.sql
INSERT INTO SPELLS(SPELL_ID, ITEM_ID)
VALUES(101, 1020),
(102, 1021),
(103, 1021),
(104, 1021)
;
INSERT INTO ITEM(ITEM_ID, NAME, ITEMTYPE, WEIGHT, RECOVERS, PRIORITY, DESC)
VALUES (1010,'Hunting Knife','DAGGER',1,5,3,''),
(1011,'Relic Sword','SWORD',3,10,3,''),
(1012,'Relic Spear','SPEAR',3,8,3, ''),
(1013,'Relic Axe','AXE',4,12,3, ''),
(1014,'Old Club','MACE',4,10,3,''),
(1015,'Crooked Stick','STAFF',2,3,3,''),
(1016,'Training Bow','BOW',2,20,4,''),
(1017,'Training Crossbow','CROSSBOW',2,20,4,''),
(1018,'Grass Sling','SLING',2,20,4,''),
(1019,'Wooden Shield','SHIELD',4,20,4,''),
(1020,'Poison wand','WAND', 1,0,4,''),
(1021,'Mushroom staff','STAFF',2,3,3,'')
;
I am getting following error after starting my spring application:
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: cannot dereference scalar collection element: metadata_descriptor_id [SELECT d FROM com.org.entity.documents.Document d INNER JOIN d.documentMetadata md ON md.document_id = d.id WHERE (md.metadata_descriptor_id.id NOT IN (:documentMetadataId))]
Here is my Document class:
#Entity
#Table(name = "documents")
public class Document {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#Column(name = "name", nullable = false, unique = true)
private String name;
#Column(name = "archived", nullable = false)
private boolean archived;
#Column(name = "creation_date", nullable = false)
private Instant creationDate;
#Column(name = "file_text_processing_status", nullable = false)
#Enumerated(EnumType.STRING)
private FileTextProcessingStatus fileTextProcessingStatus;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "template_file_id", referencedColumnName = "id")
private TemplateFile templateFile;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "state_descriptor_id", referencedColumnName = "id")
private StateDescriptor stateDescriptor;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "user_id", referencedColumnName = "id")
private UserEntity user;
#ElementCollection(targetClass = String.class)
#Column(name = "tag", nullable = false)
#CollectionTable(name = "document_tags", joinColumns = #JoinColumn(name = "document_id"))
private Set<String> tags = new HashSet<>();
#ElementCollection
#CollectionTable(name = "document_metadata", joinColumns = {
#JoinColumn(name = "document_id", referencedColumnName = "id")})
#MapKeyJoinColumn(name = "metadata_descriptor_id", referencedColumnName = "id")
#Column(name = "value", nullable = false)
private Map<MetadataDescriptor, String> documentMetadata = new HashMap<>();
#OneToMany(mappedBy = "document", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<DocumentFileVersion> documentVersions = new HashSet<>();`enter code here`
And here is Repository method that fails:
#Lock(LockModeType.PESSIMISTIC_WRITE)
#Query(value = "SELECT d FROM Document d INNER JOIN d.documentMetadata md ON md.document_id = d.id"
+ " WHERE (md.metadata_descriptor_id NOT IN (:documentMetadataId))")
List<Document> findAllByDocumentRequiredMetadataNotSet(long documentMetadataId);
I have seen an answer for similar question here: getting Caused by: org.hibernate.QueryException: cannot dereference scalar collection element: roles
But it's not helpful in my case. I will be very glad for any suggestions.
The type of md is String this is why you see an error. What you need is something like this:
#Lock(LockModeType.PESSIMISTIC_WRITE)
#Query(value = "SELECT d FROM Document d INNER JOIN d.documentMetadata md WHERE (KEY(md).id NOT IN (:documentMetadataId))")
List<Document> findAllByDocumentRequiredMetadataNotSet(long documentMetadataId);
You also had a ON clause which is no necessary/wrong. I think you should read into HQL/JPQL first as you don't seem to understand that a join of an association, will add the join predicate in the SQL automatically.
Note though, that the syntax KEY(..).id is only supported in newer Hibernate versions, so you might have to update.
I got [42000] You have an error in your SQL syntax error when I execute the HQL below:
update Status set result=18 where (userByUserId.userName like 'administrator')
And this is the corresponding SQL:
update
status cross
join
set
result=18
where
userName like 'administrator'
The results I am getting are incorrect.
But another similar query is in working order:
select count(*) from Status where (userByUserId.userName like 'administrator')
the corresponding SQL:
select
count(*) as col_0_0_
from
status status0_ cross
join
user user1_
where
status0_.userId=user1_.userId
and (
user1_.userName like 'administrator'
)
Does anyone know what happened?
Here is the code(partly):
Status.java
#Table(name = "status")
#Entity
#KeyField("statusId")
public class Status implements Serializable {
private Integer result;
#Column(name = "result", nullable = false, insertable = true, updatable = true
, length = 10, precision = 0)
#Basic
public Integer getResult() {
return result;
}
private Integer userId;
#Column(name = "userId", nullable = false, insertable = true, updatable = true
, length = 10, precision = 0)
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
private User userByUserId;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "userId", referencedColumnName = "userId", nullable = false,
insertable = false, updatable = false)
public User getUserByUserId() {
return userByUserId;
}
}
User.java
#Table(name = "user")
#Entity
#KeyField("userId")
public class User implements Serializable {
private String userName;
#Column(name = "userName", nullable = false, insertable = true, updatable = true, length = 24,
precision = 0, unique = true)
#Basic
public String getUserName() {
return userName;
}
private Collection<Status> statusesByUserId;
#OneToMany(mappedBy = "userByUserId", cascade = CascadeType.ALL)
public Collection<Status> getStatusesByUserId() {
return statusesByUserId;
}
}
I have relation as shown bellow:
#Entity
#Table(name = "ORDER_", catalog = "smartorder")
public class Order implements Serializable {
/**
* serial version id
*/
private static final long serialVersionUID = 13875615L;
#Id
#Column(name = "ORDER_ID", unique = true, nullable = false)
#SequenceGenerator(name = "ORDER_ID_GEN", sequenceName = "ORDER_ID_SEQ")
#GeneratedValue(generator = "ORDER_ID_GEN")
private long orderId;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "INVOICE_ID", referencedColumnName = "INVOICE_ID")
private Invoice invoice;
// setters and getters
}
#Entity
#Table(name = "INVOICE_")
public class Invoice implements Serializable {
/**
* serial version id
*/
private static final long serialVersionUID = 13875612L;
#Id
#Column(name = "INVOICE_ID", unique = true, nullable = false)
#SequenceGenerator(name = "INVOICE_ID_GEN", sequenceName = "INVOICE_ID_SEQ")
#GeneratedValue(generator = "INVOICE_ID_GEN")
private int invoiceId;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "ORDER_ID", referencedColumnName = "ORDER_ID")
private Order order;
#Column(name = "SUB_TOTAL", precision = 6, nullable = false)
private double subTotal;
#Column(name = "SERVICE_TAX", precision = 6, nullable = false)
private double serviceTax;
#Column(name = "VAT", precision = 6, nullable = false)
private double vat;
#Column(name = "SURCHAARGE", precision = 6, nullable = false)
private double surChaarge;
#Column(name = "GRAND_TOTAL", precision = 6, nullable = false)
private double grandTotal;
//setters and getters
}
I am able to save the records properly. But when i am trying to update orders objects by setting invoice object to order object then the order object is nor persisting only invoice object is persisting.
Order o = getSession().load(Order.class,1L);
o.setInvoice(new Invoice(.........));
getSession().update(o);
in console I am able to see one SQL statement only,
insert into INVOICE_ (DISCOUNT, GRAND_TOTAL, ORDER_ID, ROUNDING, SERVICE_TAX, SUB_TOTAL, SURCHAARGE, VAT) values (?, ?, ?, ?, ?, ?, ?, ?)
Invoice Id is not getting update in Order table :(
Can anyone suggest whats the issue is.
Thanks in advance.....
This may depend on your unusual design.
With INVOICE_ID in ORDR_ and ORDER_ID in INVOICE_ you have both tables at the same time as parent and child of each other.
If your database uses foreign keys deleting and inserting will be hard.
You should use one type/table as parent, (e. g. Order, because it's normaly first) and the other as child (order_id will be in invoice_ table).
In your object model you can have both directions (see first example of http://docs.oracle.com/javaee/6/api/javax/persistence/OneToOne.html)
The issue is incorrect scenario in which you used your Entities/Tables and the one-to-one mapping style. The concept of One-To-One does not corresponed with your current design of both tables and entities.
Please, try to read more about one-to-one here: The concept for one-to-one mapping. Explain the mapping
And mostly take a deep look here: Hibernate – One-to-One example (Annotation), where you can find examples of the one-to-one mapping.
If you really would like to continue with one-to-one mapping you have to:
Remove the "INVOICE_ID" column from the "INVOICE_" table (surprising but a fact)
make the "ORDER_ID" column in the "INVOICE_" table as a primary key (another fact)
change the mapping of the Invoice entity to be more submissive (driven by Order entity)
Example of changes of the Invoice mapping:
// just a draft, to give you idea about the
// "submissive" side mapping.
// All the ID stuff of the Invoice is driven by its
// "Master" - Order
#GenericGenerator(name = "generator", strategy = "foreign",
parameters = #Parameter(name = "property", value = "order"))
#Id
#GeneratedValue(generator = "generator")
#Column(name = "ORDER_ID", unique = true, nullable = false)
public Integer getOrderId() {
return this.orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
#OneToOne(fetch = FetchType.LAZY)
#PrimaryKeyJoinColumn
public Order getOrder() {
return this.order;
}
Please, take it as a draft, to show how different the one-to-one concept is.
I've a problem with JPA, whenever execute this query
#NamedQuery(name = "Usuario.getUsuarioIntento", query = "SELECT u.intentos_id FROM Usuario u WHERE u.username = :username and u.borrado = 0")
i get this error:
java.lang.IllegalArgumentException: NamedQuery of name: Usuario.getUsuarioIntento not found.
But if i execute this query
#NamedQuery(name = "Usuario.getUsuarioIntento", query = "SELECT u.id FROM Usuario u WHERE u.username = :username and u.borrado = 0")
Work fine,Why?
My table,Usuario:
MY USER TABLE
i try with other column as 'superusuario','version_jpa' and doesn't work, the only columns that work fine are 'id,'borrado' and 'username'
Class Usuario:
#Temporal(TemporalType.TIMESTAMP)
private Date fechaCreacion;
#Id
#GeneratedValue (strategy=GenerationType.AUTO)
private int id;
#OneToOne(cascade = CascadeType.ALL)
private Password password;
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.LAZY)
private List<Password> clavesAntiguas;
#OneToOne
private Persona persona;
private String sessionId;
private String username;
#ManyToOne(cascade = CascadeType.REFRESH)
private Rol rol;
#ManyToOne(cascade = CascadeType.REFRESH)
private Perfil perfil;
#OneToOne (cascade = CascadeType.ALL)
private IntentosBloqueo intentos;
private boolean superUsuario;
private int borrado;
private int esManager;
#OneToMany ( cascade = {CascadeType.ALL} , fetch = FetchType.LAZY)
private Collection<UsuarioSociedad> sociedades;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
#JoinTable (name="USR_UND_VIS",
joinColumns={
#JoinColumn (name="ID_USU", table="USUARIO", referencedColumnName="ID"),
},
inverseJoinColumns=
#JoinColumn (name="ID_UNI", table="UND_ORG", referencedColumnName="ID")
)
private List<UnidadOrganizativa> unidadesVisibles;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
#JoinTable (name="USR_UND_DIS",
joinColumns={
#JoinColumn (name="ID_USU", table="USUARIO", referencedColumnName="ID"),
},
inverseJoinColumns=
#JoinColumn (name="ID_UNI", table="UND_ORG", referencedColumnName="ID")
)
private List<UnidadOrganizativa> unidadesDisponibles;
Because Named query works on Entity objetc not on datbase column. You try to find another entity object which contains that id. In That case your named query will give you the object of that entity class and from that object u can get the id or whtever fiels of that entity.
JPA named query is not like SQL or oracle query.
Iin in DB your column name is xyz but in entity your column name is ABC then you have to fetch ABC in named query not XYZ.