doctrine 2 order by associative tabel - sql-order-by

I have two doctrine entities 'User' and 'Attribute', shown below. I need to construct a query that will retrieve all users and order them by attribute name where attribute type = x. For example, get all users and order them by 'title'.
SELECT u FROM User u JOIN u.attributes a ORDER BY a.name {something??} a.type = 'title'
class User {
/**
* #ManyToMany (targetEntity="Attribute", inversedBy="users", cascade={"persist"})
*
*/
private $attributes;
}
class Attribute {
/**
* #Column (type="string", length=255, unique=false, nullable=false, name="name")
* #FormElement (type="text")
* #type string
*/
protected $name;
/**
* #Column (type="string", unique=false, nullable=true, name="type")
* #type string
*/
private $type;
/**
* #Column (type="integer", length=11, unique=false, nullable=true, name="priority")
* #type integer
*/
private $priority;
/**
* #ManyToMany (targetEntity="User", mappedBy="attributes")
*/
private $users;
}

I think this query is what you are looking for:
SELECT u FROM User u JOIN u.attributes a WHERE a.type = 'title' ORDER BY a.name ASC

Related

ERROR: null value in column "album_id" of relation "songs" violates not-null constraint

The entity classes are as given below
I am not sure if this is problem with how Hibernate or Spring Data understands my input. In my project on backend I am using Java + Spring Data + Hibernate + PostgreSQL.
I am able to get and delete data from the database but not add to it.
//AlbumEntity
``
#Entity
#Table(name = "albums")
public class AlbumEntity extends ApplicationPersistenceEntity implements Album {
#Id
#Column(name = "album_id")
// #GeneratedValue(strategy = GenerationType.IDENTITY)
private long albumId;
#Column(name = "NAME")
private String albumName;
#Column(name = "Genre")
private String genre;
#ManyToOne(cascade = CascadeType.PERSIST, optional = true, fetch = FetchType.LAZY)
#JoinColumn(name = "singer_id", nullable = false)
// #NotFound(action = NotFoundAction.IGNORE)
private SingerEntity singer;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "album")
private List<SongEntity> songs;
private static final long serialVersionUID = 1L;
/**
* The constructor.
*/
public AlbumEntity() {
}
/**
* The constructor.
*
* #param albumId
* #param albumName
* #param genre
* #param singer
* #param songs
*/
public AlbumEntity(long albumId, String albumName, String genre, SingerEntity singer, List<SongEntity> songs) {
super();
this.albumId = albumId;
this.albumName = albumName;
this.genre = genre;
this.singer = singer;
this.songs = songs;
}
/**
* #return albumId
*/
#Override
public long getAlbumId() {
return this.albumId;
}
/**
* #param albumId new value of {#link #getalbumId}.
*/
#Override
public void setAlbumId(long albumId) {
this.albumId = albumId;
}
/**
* #return albumName
*/
#Override
public String getAlbumName() {
return this.albumName;
}
/**
* #param albumName new value of {#link #getalbumName}.
*/
#Override
public void setAlbumName(String albumName) {
this.albumName = albumName;
}
/**
* #return genre
*/
#Override
public String getGenre() {
return this.genre;
}
/**
* #param genre new value of {#link #getgenre}.
*/
#Override
public void setGenre(String genre) {
this.genre = genre;
}
/**
* #return singer
*/
public SingerEntity getSinger() {
return this.singer;
}
/**
* #param singer new value of {#link #getsinger}.
*/
public void setSinger(SingerEntity singer) {
this.singer = singer;
}
/**
* #return songs
*/
public List<SongEntity> getSongs() {
return this.songs;
}
/**
* #param songs new value of {#link #getsongs}.
*/
public void setSongs(List<SongEntity> songs) {
this.songs = songs;
}
#Override
#Transient
public Long getSingerId() {
if (this.singer == null) {
return null;
}
return this.singer.getId();
}
#Override
public void setSingerId(Long singerId) {
if (singerId == null) {
this.singer = null;
} else {
SingerEntity singerEntity = new SingerEntity();
singerEntity.setId(singerId);
this.singer = singerEntity;
}
}
}
//Song Entity
#Entity
#Table(name = "songs")
public class SongEntity extends ApplicationPersistenceEntity implements Song {
#Id
#Column(name = "song_id")
// #GeneratedValue(strategy = GenerationType.IDENTITY)
private long songId;
#Column(name = "Title")
private String title;
#Column(name = "Content")
private String content;
#ManyToOne(cascade = CascadeType.PERSIST, optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "singer_id", nullable = false)
private SingerEntity singer;
#ManyToOne(cascade = CascadeType.PERSIST, optional = true, fetch = FetchType.LAZY)
#JoinColumn(name = "album_id")
private AlbumEntity album;
private static final long serialVersionUID = 1L;
/**
* The constructor.
*/
public SongEntity() {
}
/**
* The constructor.
*
* #param songId
* #param title
* #param content
* #param singer
* #param album
*/
public SongEntity(long songId, String title, String content, SingerEntity singer, AlbumEntity album) {
super();
this.songId = songId;
this.title = title;
this.content = content;
this.singer = singer;
this.album = album;
}
/**
* #return songId
*/
#Override
public long getSongId() {
return this.songId;
}
/**
* #param songId new value of {#link #getsongId}.
*/
#Override
public void setSongId(long songId) {
this.songId = songId;
}
/**
* #return title
*/
#Override
public String getTitle() {
return this.title;
}
/**
* #param title new value of {#link #gettitle}.
*/
#Override
public void setTitle(String title) {
this.title = title;
}
/**
* #return content
*/
#Override
public String getContent() {
return this.content;
}
/**
* #param content new value of {#link #getcontent}.
*/
#Override
public void setContent(String content) {
this.content = content;
}
/**
* #return singer
*/
public SingerEntity getSinger() {
return this.singer;
}
/**
* #param singer new value of {#link #getsinger}.
*/
public void setSinger(SingerEntity singer) {
this.singer = singer;
}
/**
* #return album
*/
public AlbumEntity getAlbum() {
return this.album;
}
/**
* #param album new value of {#link #getalbum}.
*/
public void setAlbum(AlbumEntity album) {
this.album = album;
}
#Override
#Transient
public Long getSingerId() {
if (this.singer == null) {
return null;
}
return this.singer.getId();
}
#Override
public void setSingerId(Long singerId) {
if (singerId == null) {
this.singer = null;
} else {
SingerEntity singerEntity = new SingerEntity();
singerEntity.setId(singerId);
this.singer = singerEntity;
}
}
#Override
#Transient
public Long getAlbumId() {
if (this.album == null) {
return null;
}
return this.album.getId();
}
#Override
public void setAlbumId(Long albumId) {
if (albumId == null) {
this.album = null;
} else {
AlbumEntity albumEntity = new AlbumEntity();
albumEntity.setId(albumId);
this.album = albumEntity;
}
}
}
singer entity
#Entity
#Table(name = "singers")
public class SingerEntity extends ApplicationPersistenceEntity implements Singer {
#Id
#Column(name = "singer_id")
// #GeneratedValue(strategy = GenerationType.IDENTITY)
private long singerId;
#Column(name = "First_NAME")
private String firstname;
#Column(name = "Last_NAME")
private String lastname;
#Column(name = "Gender")
private String gender;
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "singer")
private List<SongEntity> songs;
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "singer")
private List<AlbumEntity> albums;
private static final long serialVersionUID = 1L;
/**
* The constructor.
*/
public SingerEntity() {
}
/**
* The constructor.
*
* #param singerId
* #param firstname
* #param lastname
* #param gender
* #param songs
* #param albums
*/
public SingerEntity(long singerId, String firstname, String lastname, String gender, List<SongEntity> songs,
List<AlbumEntity> albums) {
super();
this.singerId = singerId;
this.firstname = firstname;
this.lastname = lastname;
this.gender = gender;
this.songs = songs;
this.albums = albums;
}
/**
* #return singerId
*/
#Override
public long getSingerId() {
return this.singerId;
}
/**
* #param singerId new value of {#link #getsingerId}.
*/
#Override
public void setSingerId(long singerId) {
this.singerId = singerId;
}
/**
* #return firstname
*/
#Override
public String getFirstname() {
return this.firstname;
}
/**
* #param firstname new value of {#link #getfirstname}.
*/
#Override
public void setFirstname(String firstname) {
this.firstname = firstname;
}
/**
* #return lastname
*/
#Override
public String getLastname() {
return this.lastname;
}
/**
* #param lastname new value of {#link #getlastname}.
*/
#Override
public void setLastname(String lastname) {
this.lastname = lastname;
}
/**
* #return gender
*/
#Override
public String getGender() {
return this.gender;
}
/**
* #param gender new value of {#link #getgender}.
*/
#Override
public void setGender(String gender) {
this.gender = gender;
}
/**
* #return songs
*/
public List<SongEntity> getSongs() {
return this.songs;
}
/**
* #param songs new value of {#link #getsongs}.
*/
public void setSongs(List<SongEntity> songs) {
this.songs = songs;
}
/**
* #return albums
*/
public List<AlbumEntity> getAlbums() {
return this.albums;
}
/**
* #param albums new value of {#link #getalbums}.
*/
public void setAlbums(List<AlbumEntity> albums) {
this.albums = albums;
}
}
While checking Post endpoint
"modificationCounter": 2,
"id": 302,
"songId": 302,
"title": "As it was",
"content": "songs",
"singer_id": 201,
"album_id": 101
I am giving this data...still there is this error
org.postgresql.util.PSQLException: ERROR: null value in column "album_id" of relation "songs" violates not-null constraint
Detail: Failing row contains (302, 2, 302, As it was, songs, null, null).
This one keeps on coming... I guess you are using your entities as DTOs. DON'T
The problem is that you send an ID for albumID and singerID which are objects in Java.
For this to work, create a DTO that maps your fields and lookup the IDs in your database then create your Song Entity with those. Also, you need to map back the song in your album and singer for JPA to work correctly.

foreign key of previously saved data is updated as null in spring boot while saving for second time

Developing an application of shopping cart below are my entity classes....
When i save it for the first time user entity is saved properly when same request is used to save user again then previously saved foreign key is becoming null i am using same request because, for same user, for same cart ,cart products have to updated in multiple rows.
#Entity
public class CartProduct implements Serializable {
/**
* serialVersionUID.
*/
private static final long serialVersionUID = 5846027470952949766L;
/**
* cartProdcutId.
*/
#Id
#GeneratedValue
#Column(name = "CART_PRODUCT_ID")
private Integer cartProdcutId;
/**
* product.
*/
#ManyToOne
#JoinColumn(name = "PRODUCT_ID")
private Product product;
/**
* cart.
*/
#ManyToOne
#JoinColumn(name = "CART_ID")
private Cart cart;
/**
* quantity.
*/
#Min(value = 0, message = "Product Quantity should not be negative")
#Column(name = "QUANTITY")
private Integer quantity;
}
second class
#Entity
public class Cart {
/**
* cartId.
*/
#Id
#GeneratedValue
#Column(name = "CART_ID")
Integer cartId;
/**
* cartProducts.
*/
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "CART_ID")
Set<CartProduct> cartProducts = new HashSet<CartProduct>();
}
Saving User class
#Entity
public class User {
/**
* userId.
*/
#Id
#GeneratedValue
#Column(name = "USER_ID")
Integer userId;
/**
* userName.
*/
#Column(name = "USER_NAME")
String userName;
/**
* cart.
*/
#OneToOne(cascade = CascadeType.ALL)
Cart cart;
}
Product Class
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#NamedQueries({ #NamedQuery(name = "Product.findBook", query = "SELECT p FROM Product p WHERE TYPE(p) = Book"),
#NamedQuery(name = "Product.findApparal", query = "SELECT p FROM Product p WHERE TYPE(p) = Apparal"),
#NamedQuery(name = "Product.findByName", query = "SELECT p FROM Product p WHERE p.productName=:name") })
public class Product {
/**
* productId.
*/
#Id
#GeneratedValue
#Column(name = "PRODUCT_ID")
Integer productId;
/**
* productName.
*/
#Column(name = "PRODUCT_NAME")
String productName;
/**
* price.
*/
#Column(name = "PRICE")
Float price;
}
Service method to save User
userRepository.save(user);
Json used in postman to save User entity:
{
"cart": {
"cartId": 1,
"products": [
{
"cartProdcutId": 1,
"product": {
"price": 100,
"productId": 1,
"productName": "ProdNameOne"
},
"quantity": 1
}
]
},
"userId": 1,
"userName": "USERONE"
}
Below is the data base screen shot where null is updated in first row :Data base screen shot

To get the field name in an entity using column name

Is there any way to get the field name in an entity using column name.
#Table(name = "ESTABLISHMENT")
public class Establishment implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#Column(name = "EST_CODE")
private Long code;
#Column(name = "W_CODE")
private Long wCode;
}
//service
I have W_CODE name is there any way to get the field name in the entity. Here its wCode.
I want to use that to create a custom JPQL query.
You can parse the column annotations:
for (Field field : entity.getClass().getDeclaredFields()) {
Column column = field.getAnnotation(Column.class);
if (column != null) {
columnNames.add(column.name());
}
}
You can get the Column name list using your Entity or Model. What we need is #Column, which should be used in your Entity. You will get all the details which you have specified in #Column. All the parameters are optional, although it is good to define all.
#Column(name, columnDefinition, insertable, length, nullable,
precision, scale, table, unique, updatable)
We can get all fields declared in Entity by User.class.getDeclaredFields() ( in general ModelName.class.getDeclaredFields()). After getting all feilds we can get particular Column using field.getAnnotation(Column.class) we can also get all the details specified in #Column as below
Columns: #javax.persistence.Column(nullable=false, precision=2, unique=true, name=id, length=2, scale=1, updatable=false, columnDefinition=, table=, insertable=true)
Columns: #javax.persistence.Column(nullable=true, precision=0, unique=false, name=client_id, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true)
Columns: #javax.persistence.Column(nullable=true, precision=0, unique=false, name=firstname, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true)
Columns: #javax.persistence.Column(nullable=true, precision=0, unique=false, name=lastname, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true)
create endPoint or method as per requirement
#GetMapping(value= "/columns/name")
public List<String> tableColumnsName()
{
List<String> Columns = new ArrayList<String>();
Field[] fields = User.class.getDeclaredFields();
for (Field field : fields) {
Column col = field.getAnnotation(Column.class);
if (col != null) {
Columns.add(col.name());
System.out.println("Columns: "+col);
}
}
return Columns;
}

Apache ignite query from set

is it possible to query values from set? for example,
public class Employee implements Serializable {
/** Person ID (indexed). */
#QuerySqlField(index = true)
private long id;
/** Department ID (indexed). */
#QuerySqlField(index = true)
private Set deptIds;
/** First name (not-indexed). */
#QuerySqlField
private String firstName;
/** Last name (not indexed). */
#QuerySqlField
private String lastName;
}
now i want to get all employee for one particular department.
It is possible with Scan queries, but not possible with SQL queries.
Looks like you use SQL queries. In this case you have to think in terms of relational databases. There is a many-to-many relationship between Employee and Department, so you have to add a Junction Table.
public class EmployeeDepartment implements Serializable {
/** Person ID (indexed). */
#QuerySqlField(index = true)
private long personId;
/** Department ID (indexed). */
#QuerySqlField(index = true)
private long deptId;
}
After that you can do a three way join to find employees for a particular department.

Hibernate table foreign key Insertion: #OneToMany/#ManyToOne relation

I'm working with hibernate 4 and Maven :
package tn.onp.mvno.model;
#Entity
#Table(name="PERSON")
public class Person {
private int id;
private String name;
private String surname;
private String email;
private String adresse;
private String MobilePhone;
/**
* Get User Id
*
* #return int - User Id
*/
#Id
#GeneratedValue
#Column(name="ID")
public int getId() {
return id;
}
/**
* Set User Id
*
* #param int - User Id
*/
public void setId(int id) {
this.id = id;
}
}
package tn.onp.mvno.model;
#Entity
#Inheritance(strategy= InheritanceType.TABLE_PER_CLASS)
#Table(name="USER")
public class User extends Person{
private String SIMCardNumber;
private String SIMCardValidityDate;
private Collection<Call> calls;
private Collection<Credit> credits;
#Column(name="SIMCARDNUMBER", unique = true, nullable = false)
public String getSIMCardNumber() {
return SIMCardNumber;
}
public void setSIMCardNumber(String sIMCardNumber) {
SIMCardNumber = sIMCardNumber;
}
#Column(name="SIMCARDVALIDITYDATE", nullable = false)
public String getSIMCardValidityDate() {
return SIMCardValidityDate;
}
public void setSIMCardValidityDate(String sIMCardValidityDate) {
SIMCardValidityDate = sIMCardValidityDate;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
public Collection<Call> getCalls() {
return calls;
}
public void setCalls(Collection<Call> calls) {
this.calls = calls;
}
}
Call.java
#Entity
#Table(name="CALL")
public class Call {
private String callId;
private String telNumber;
private String term;
private String duration;
private String direction;
private User user;
/** Get the callId
* #return the callId
*/
#Id
#GeneratedValue
#Column(name="CALLID")
public String getCallId() {
return callId;
}
/** Set the callId
* #param callId the callId to set
*/
public void setCallId(String callId) {
this.callId = callId;
}
/** Get the telNumber
* #return the telNumber
*/
#Column(name="TELNUMBER")
public String getTelNumber() {
return telNumber;
}
/** Set the telNumber
* #param telNumber the telNumber to set
*/
public void setTelNumber(String telNumber) {
this.telNumber = telNumber;
}
/** Get the term
* #return the term
*/
#Column(name="TERM")
public String getTerm() {
return term;
}
/** Set the term
* #param term the term to set
*/
public void setTerm(String term) {
this.term = term;
}
/** Get the duration
* #return the duration
*/
#Column(name="DURATION")
public String getDuration() {
return duration;
}
/** Set the duration
* #param duration the duration to set
*/
public void setDuration(String duration) {
this.duration = duration;
}
/** Get the direction
* #return the direction
*/
#Column(name="DIRECTION")
public String getDirection() {
return direction;
}
/** Set the direction
* #param direction the direction to set
*/
public void setDirection(String direction) {
this.direction = direction;
}
/** Get the user
* #return the user
*/
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id")
public User getUser() {
return user;
}
/** Set the user
* #param user the user to set
*/
public void setUser(User user) {
this.user = user;
}
}
When i deploy the application on tomcat server and run it i get this error :
INFO: HHH000227: Running hbm2ddl schema export
Hibernate: alter table CALL drop foreign key FK1F725EE04824FE
févr. 11, 2013 5:53:38 PM org.hibernate.tool.hbm2ddl.SchemaExport perform
ERROR: HHH000389: Unsuccessful: alter table CALL drop foreign key FK1F725EE04824FE
févr. 11, 2013 5:53:38 PM org.hibernate.tool.hbm2ddl.SchemaExport perform
ERROR: You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'CALL drop foreign key
FK1F725EE04824FE' at line 1
Hibernate: drop table if exists CALL
févr. 11, 2013 5:53:38 PM org.hibernate.tool.hbm2ddl.SchemaExport perform
ERROR: HHH000389: Unsuccessful: drop table if exists CALL
févr. 11, 2013 5:53:38 PM org.hibernate.tool.hbm2ddl.SchemaExport perform
ERROR: You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'CALL' at line 1
Hibernate: drop table if exists CREDIT
Hibernate: drop table if exists PERSON
Hibernate: create table CALL (CALLID varchar(255) not null auto_increment, DIRECTION
varchar(255), DURATION varchar(255), TELNUMBER varchar(255), TERM varchar(255), id
integer, primary key (CALLID))
févr. 11, 2013 5:53:38 PM org.hibernate.tool.hbm2ddl.SchemaExport perform
ERROR: HHH000389: Unsuccessful: create table CALL (CALLID varchar(255) not null
auto_increment, DIRECTION varchar(255), DURATION varchar(255), TELNUMBER varchar(255),
TERM varchar(255), id integer, primary key (CALLID))
févr. 11, 2013 5:53:38 PM org.hibernate.tool.hbm2ddl.SchemaExport perform
ERROR: You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'CALL (CALLID varchar(255) not
null auto_increment, DIRECTION varchar(255), DURAT' at line 1
CALL is a reserved word. Choose another table name.

Resources