I have strange error here...
I have two databases configurated on this project, and when i try to save into local mysql repository, i get the title error.
In addition i have remote oracle db in use.
Hibernate:
select
hibernate_sequence.nextval
from
dual
and then
[nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown table 'hibernate_sequence' in field list
and there is no table named hibernate.sequence in database, or attribute in class.
#Id
#GeneratedValue
long id;
#Column(name = "customerid")
private String customerid;
#OneToMany(targetEntity = C_Portfolio.class, fetch = FetchType.LAZY, cascade = {CascadeType.ALL}, orphanRemoval=true)
#Fetch(FetchMode.SELECT)
private List<C_Portfolio> portfolios;
#Column(name = "date")
private LocalDate date;
#Column(name = "date_time")
private LocalDateTime datetime;
Furthermore everything seems to be okey just before the save. When i check the class to be saved in debugger mode. it has all the needed values and everything seems to be okey.
You have simply used #GeneratedValue in the POJO, so it tries to find the sequence table. Since you haven't specified the sequence table name, it will look for default sequence table "hibernate_sequence".
For mysql it increments the value by specifying as like below in your POJO:
#GeneratedValue(strategy = GenerationType.AUTO)
If you use it, it will generate a table called hibernate_sequence to provide the next number for the ID sequence.
Related
I have the following entity class:
#Entity
#Table(name = "employee")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
#NotNull
#NaturalId
private String tagId;
#NotNull
#Size(max = 255, message = "Employee name can not be longer than 255 character")
private String name;
#Type(type = "yes_no")
private boolean isInside;
#PastOrPresent(message = "Last RFID timestamp can not be in the future")
private ZonedDateTime lastSwipe;
//Constuctors, getters and setters
}
With the following JpaRepository:
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
Optional<Employee> findByTagId(String tagId);
}
Let's say I have an employee in the database, with tagId "SomeStringForID".
Right now, if I query the database using the findByTagId method where tagId equals "sOmEStringforid" for example, the employee is found in the database. If I try to save another employee with tagId "sOmEStringforid", I will get an exception, thanks to the #NaturalId annotation.
Any idea what causes this behaviour? Spring named queries have options for IgnoreCase, so I'm pretty sure this should not be the default behaviour. I checked one of my older projects too, where to my surprise I have found the same behaviour. I tried both JDK 8 and 11 versions.
MySQL is not case sensitive. You can query for a record using a value of 'a' and it can return a record 'A' or 'a'.
See the following:
MySQL case insensitive select
MySQL case sensitive query
How can I make SQL case sensitive string comparison on MySQL?
I am begginer in Hibernate and i have a table named suffrages1 with no relations to the rest of the database.
The table has an autoincrement identifier field named Suffrages_id.
In the corresponding entity, i am declaring the field as follows :
#Entity(name = "suffrages1")
public class Suffrage1 implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#JoinColumn(name = "Suffrages_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
The insertion is fine but when i try to fetch i get this error :Unknown column 'this_.id' in 'field list'
All similar issues i found were about problems with relationships between tables or about correct column names for mapping but as i said this table has no relationship with other table and i think i have the correct names e,g i know that my Java variable in the class is named id but is annotated with #JoinColumn to correspond to the Mysql column. So where did 'this_.id' come from ?
Sorry, i was using #JoinColumn instead of #Column to define the id field.
I have one of the weird issues that make you growl. I'm having (also weird) Spring/Hibernate application, that is intended to manage database in following way (i've simplified some things, so don't be confused that source code mentions slightly different tables/columns):
active_proxy_view table:
id | entity
<uuid> | <string containing json>
archive_proxy_view table:
id | entity
<uuid> | <string containing json>
track_reference table:
ref_type | ref_id | track_domain | track_type | track_id |
'proxy' | <uuid> | 'example.com' | 'customer' | '123' |
Keeping two tables is mandatory - i need to have both all-time-history/statistical queries and business-value queries only for things that being active right now, so i need to keep set for active proxies tight. track_reference table is used for searches so i could do queries like that:
SELECT p.id, p.entity FROM archive_proxy_view AS p
INNER JOIN track_reference AS t1 ON
t1.ref_id = p.id AND
t1.ref_type = 'proxy' AND
t1.track_domain = 'example.com' AND
t1.track_type = 'customer' AND
t1.track_id = '123'
INNER JOIN track_reference AS t2 ON
t2.ref_id = p.id AND
t2.ref_type = 'proxy' AND
t2.track_domain = 'example.com' AND
t2.track_type = 'campaign' AND
t2.track_id = 'halloween-2017'
(it may be not 100% correct, i haven't raw sql experience in a while)
And here's the problem:
Both active_proxy_view and archive_proxy_view entities are inherited from one class that specifies #OneToMany relationship on track_reference entity; #ManyToOne usage is not really possible, because there are many entities tied to tracking reference
track_reference is managed separately (and this is mandatory too)
I need to manage views separately from track_reference table, but whenever i tell Hibernate to remove entity from active_proxy_view table, it takes away track_reference entities as well. Even if i play with cascade annotation value, which is blank by default (and as i understand, it means that child records should not be deleted with parent). There is possibility that i've missed something, though.
I also failed to hack the whole thing using custom #SQLDeleteAll, i still can see regular deletes in general log:
55 Query delete from tracking_reference where referenced_entity_id='13c6b55c-f9b7-4de7-8bd4-958d487e461c' and referenced_entity_type='proxy' and tracked_entity_type='agent'
55 Query delete from tracking_reference where referenced_entity_id='13c6b55c-f9b7-4de7-8bd4-958d487e461c' and referenced_entity_type='proxy' and tracked_entity_type='lead'
55 Query delete from tracking_reference where referenced_entity_id='13c6b55c-f9b7-4de7-8bd4-958d487e461c' and referenced_entity_type='proxy' and tracked_entity_type='source'
53 Query DELETE FROM `tracking_reference` WHERE `referenced_entity_type` = 'proxy' AND referenced_entity_id = '13c6b55c-f9b7-4de7-8bd4-958d487e461c' AND 1 = 0
I'm using Hibernate 5.2.3.Final through Spring 4.3.2.RELEASE / Spring Data JPA 1.10.2.RELEASE
TL; DR
So, the question is: how do i prevent Hibernate from deleting associated entities when parent is deleted?
The source code for entities looks like this:
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class ProxyViewEntryTemplate {
#Id
#NotNull
#Column(nullable = false)
private String id;
#NotNull
#Column
private String entity;
// some other columns
#OneToMany
#JoinColumn(name = TrackRef.REFERENCE_ID_COLUMN_NAME) // 'reference_entity_id`
#Where(clause = ProxyView.TRACK_WHERE_JOIN_CLAUSE) // `referenced_entity_type` = 'proxy'
#SQLDeleteAll(sql = ProxyView.TRACK_DELETE_ALL_QUERY) // DELETE FROM `tracking_reference` WHERE `referenced_entity_type` = 'proxy' AND referenced_entity_id = ? AND 1 = 0
private Collection<TrackingReference> track = new ArrayList<>();
// setters, getters, hashCode, equals
}
#Entity
#Table(name = "active_proxy")
public class ActiveProxyViewEntry extends ProxyViewEntryTemplate {}
#Entity
#Table(name = "tracking_reference")
#IdClass(TrackingReferenceId.class)
public class TrackingReference {
#Id
#Column(name = "tracked_entity_type", nullable = false)
#NotNull
private String trackedType;
#Id
#Column(name = "tracked_entity_domain", nullable = false)
private String trackedDomain;
#Id
#Column(name = "tracked_entity_id", nullable = false)
private String trackedId;
#Id
#Column(name = "referenced_entity_type", nullable = false)
#NotNull
private String referencedType;
#Id
#Column(name = "referenced_entity_id", nullable = false)
#NotNull
private String referencedId;
// setters, getters, hashCode, equals
}
The whole thing is managed through Spring JPA Repositories:
#NoRepositoryBean
public interface SuperRepository<E, ID extends Serializable> extends PagingAndSortingRepository<E, ID>,
JpaSpecificationExecutor<E> {
}
public interface ActiveProxyViewRepository extends SuperRepository<ActiveProxyViewEntry, String> {}
// the call for deletion
public CompletableFuture<Void> delete(ID id) {
...
descriptor.getRepository().delete(descriptor.getIdentifierConverter().convert(id));
...
}
// which is equal to
...
ActiveProxyViewRepository repository = descriptor.getRepository();
String uuidAsString = descriptor.getIdentifierConverter().convert(id);
repository.delete(uuidAsString);
...
If you remove the #JoinColumn, you shouldn't have this problem.
If you need to keep the #JoinColumn, you need to remove the foreign-key constraint requirement that gets automatically applied by the persistence provider by changing the annotation to:
#JoinColumn(
name = "yourName"
foreignKey = #Foreignkey(value = ConstraintMode.NO_CONSTRAINT)
)
You should then be able to delete the view entity without forcing the tracking references to be removed.
It turned out to be a typical shoot yourself in the foot scenario.
Tracking references were updated in a rather sophisticated way:
Build collection of references to be stored in database (C1)
Load all present references (C2)
Store C1
Delete all references that are present in C2 but not referenced in C1 (using collection.removeAll)
And it turned out that my .equals method has been written terribly wrong, returning false in nearly in each case. Because of that, usually every reference was deleted from database (the queries you can see in the log in question), so it was my fault.
After i've fixed that, only #SQLDeleteAll query was run - for reasons not known to me, it still acted like if cascade option was set. I managed to get rid of it using #OneToMany(updatable = false, insertable = false); it seems like a dirty hack, but i don't have enough time to dig it through.
I haven't tested it thoroughly yet, but, i hope, that solves the problem.
I know this makes none sense as many tutorials state that you can use SecondaryTable annotation, however it doesn't work in hibernate. I have schema like this:
#Entity
#Table(name="server")
#SecondaryTable(name="cluster", pkJoinColumns = { #PrimaryKeyJoinColumn(name = "uuid", referencedColumnName = "cluster_uuid") })
public class Server {
#Id
#Column(name = "uuid")
private String uuid;
#Column(name = "cluster_uuid")
private String clusterUuid;
#Column(name = "ip", table="cluster")
private String ip;
..... }
#Entity
#Table(name = "cluster")
public class Cluster {
#Id
#Column(name = "uuid")
private String uuid;
#Column(name = "ip")
private String ip;
.....
}
Server.clusterUuid is a foreign key to Cluster.uuid. I am hoping to get Server entity that fetches ip column from Cluster by joining Server.clusterUuid to Cluster.uuid.
Then I was greeted by a hibernate exception:
Caused by: org.hibernate.AnnotationException: SecondaryTable
JoinColumn cannot reference a non primary key
at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:402)
at org.hibernate.cfg.annotations.EntityBinder.bindJoinToPersistentClass(EntityBinder.java:620)
at org.hibernate.cfg.annotations.EntityBinder.createPrimaryColumnsToSecondaryTable(EntityBinder.java:612)
I see lots of people encountered this problem. But the first bug for this in Hibernate's bugzilla was 2010, I am surprised it's been there for over two years as this is supposed to be a basic feature. There is some post saying JPA spec only allows primary key to do the mapping, however, I get below from JPA wikibook
JPA allows multiple tables to be assigned to a single class. The
#SecondaryTable and SecondaryTables annotations or
elements can be used. By default the #Id column(s) are assumed to be
in both tables, such that the secondary table's #Id column(s) are the
primary key of the table and a foreign key to the first table. If
the first table's #Id column(s) are not named the same the
#PrimaryKeyJoinColumn or can be used to
define the foreign key join condition.
it's obviously OK for non-primary key. Then I am confused why Hibernate didn't fix this problem as it seems to be easy to implement by a join clause.
anybody knows how to overcome this problem? thank you.
I don't quite understand your setup.
#SecondaryTable is for storing a single entity in multiple tables, but in your case you have a many-to-one relationship between different entities (each one stored in its own table), and it should be mapped as such:
#Entity
#Table(name="server")
public class Server {
#ManyToOne
#JoinColumn(name = "cluster_uuid")
private Cluster cluster;
...
}
I have been searching through different forums for information and I have tried different solutions, but I'm still unable to correct my issue.
I am using hibernate4 annotations for mapping my entities. Auto increment key is not detected when tables are created using hibernate in mysql.
I have the following code:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(unique = true, nullable = false)
private int responseId;
I have also tried:
#Id
#GenericGenerator(name="generator", strategy="increment")
#GeneratedValue(generator="generator")
private int responseId;
With hibernate the id is automatically assigned to a row, but in the mysql table it has no AutoIncrement Constraint. I have to mark field as AI manually. This becomes problematic when I manually insert a record for testing or use jdbc statements for the table. Please let me know what I am missing in configuration that is preventing the hibernate id from assigning an AutoIncrement Contraint.
Use the IDENTITY generator, and use the columnDefinition attribute of #Column to specify the type of the column:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(columnDefinition = "MEDIUMINT NOT NULL AUTO_INCREMENT")
private int responseId;