Getting a list of columns by a list of identifiers - mysql

There is a Product entity.
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, unique = true)
private Long id;
#Column(name = "url_img1", nullable = false, length = 50)
private String urlImg1;
Product has an ID field and a urlImg field.
There is a list of Product identifiers.
List<Long> list = new ArrayList<>();
list.add(1L);
list.add(2L);
How can I get all urlImgs of these identifiers using JPA request?
#Query()
List<String> ();

By using a basic query like this select p.urlImg1 from Product p where p.id in :productIds

Related

how can I create a Single Entity from two other tables/Entity JPA hibernate making a INNER JOIN result with a common key

How can I create a Single Entity from two other tables/Entity in JPA/hibernate making a INNER JOIN result with a common key. I was using the below code but it gives me a full join instead of an inner join. it give me records from the meal table even if the
"id 1" does not exist in the allergies table, example:
{id=1, name='tacos', description='Mexican food', price ='10',peanuts=null, celery=null, sesameSeeds=null}
How can constrain to don't return any records if the 'id' is missing from the secondary table allergies? to show only records when the primary key is present in both tables.
I want something like this instead:
{id=1, name='tacos', description='Mexican food', price ='10',peanuts='no', celery='no', sesameSeeds='no'}
Please advise.
#Entity
#Table(name = "meal")
#SecondaryTable(name = "allergens", pkJoinColumns = #PrimaryKeyJoinColumn(name = "meal_id"))
class Meal {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
Long id;
#Column(name = "name")
String name;
#Column(name = "description")
String description;
#Column(name = "price")
BigDecimal price;
#Column(name = "peanuts", table = "allergens")
boolean peanuts;
#Column(name = "celery", table = "allergens")
boolean celery;
#Column(name = "sesame_seeds", table = "allergens")
boolean sesameSeeds;
// standard getters and setters
}

Spring Data JPA - How to query table with no entity class?

I am working on below database tables :
users table - Each row represents a User in the system. It has a foreign key constraint to countries table.
countries table - Each row represents a Country and each country can have a list of dialects stored in table dialects.
I am using Spring data JPA and have created below entity classes
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "full_name")
private String fullName;
#Column(name = "createdAt")
private Date createdAt;
#Column(name = "country_code")
private Integer countryCode;
#Column(name = "dialect_key")
private String dialectKey;
}
public class Country {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer country_code;
#Column(name = "name")
private String name;
#Column(name = "continent_name")
private String continentName;
#ElementCollection
#CollectionTable(name = "Dialect", joinColumns = { #JoinColumn(name = "country_code") })
private List<Dialect> dialectList;
}
#Embeddable
public class Dialect {
private String name;
}
Now I have a use case where I need to fetch the full name and dialect name for a given User.
Select u.full_name, d.name from users u
join countries c on u.country_code = c.country_code
join dialects d on c.country_code = d.country_code
where u.id = :user_id and u.dialect_key = d.dialect_key
Question - The above query works fine when ran as a native query and returns a List of Object. Further I am mapping the Objects List to the List of POJO. Is there a better way to do this to avoid Object -> POJO conversion explicitly ?

Hibernate HQL query get data from table associated with another table

I have an entity called Locality as:-
#Entity
#Table(name = "CMN_LOCALITY_MASTER")
public class Locality {
#Id
#Column(name = "LOCALITY_ID", unique = true, nullable = false,length = 11)
#GeneratedValue(strategy = GenerationType.IDENTITY)
int localityId;
#Column(name = "LOCALITY_DESCRIPTION",length=70)
String localityDescription;
#JsonProperty(access = Access.WRITE_ONLY)
#ManyToOne
#JoinColumn(name = "PINCODE_ID")
Pincode pinCode;
#JsonIgnore
#ManyToOne
City city;
}
which contains another entity called City and Pincode.
City is as below:-
#Entity
#Table(name = "CMN_CITY_MASTER")
public class City{
#Id
#Column(name = "CITY_ID", unique = true, nullable = false,length = 11)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int cityId;
#Column(name = "CITY",length = 150)
private String description;
#JsonIgnore
#ManyToOne
#JoinColumn(name = "STATE_ID")
private State state;
}
I want to Get all data from Locality entity/table which has City ID = (e.g. 1)
I tried below queries:-
#Query("SELECT a FROM Locality a INNER JOIN a.city c WHERE c.cityId=?1")
List<Locality>getAllLocalityByCity(int cityId);
and also
#Query("SELECT a FROM Locality a WHERE a.city.cityId=?1")
List<Locality>getAllLocalityByCity(int cityId);
But these are not working.
Could you please suggest me something/way to query the data?
Also, is there an Eclipse Plug-In/Tool to test HQL queries in a faster way than restarting the server for every change in the query?
Could you also suggest reading documents/book for learning HQL?
Since you are not providing any logs or explanation I can suggest you try the following:
#Query("SELECT a FROM Locality a INNER JOIN a.city c WHERE c.cityId = :cityId")
List<Locality>getAllLocalityByCity(#Param("cityId") int cityId);
For learning the HQL I would start with Hibernate Docs. You can take a look at Criteria API as well.

Converting SQL query to JPA NamedQuery

I'm trying to implement a Keyword search functionality that returns a List of Keyword entities based on a field text match.
Right now, the query
select * from photo_keywords pk
inner join keywords k on pk.photo_id = k.keyword_id
inner join photos p on pk.keyword_id = p.photo_id
where k.keyword LIKE "%$SOME_SEARCH_VALUE%";
returns all matching photos for a given keyword search. I'd like to have this adapted to a #NamedQuery with the following Entity objects:
#Entity
#Table(name = "keywords")
public class Keyword implements Serializable{
#Id
#Column(name = "keyword_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column
private String keyword;
#ManyToMany(mappedBy = "keywords")
private List<Photo> photos;
//getters and setters
}
and
#Entity
#Table(name = "photos")
public class Photo implements Serializable{
#Id
#Column(name = "photo_id", nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "photo_name", nullable = false)
private String photoName;
#Column(name = "photo_path", nullable = false)
private String photoPath;
#Column(name = "upload_date", nullable = false)
private Date uploadDate;
#Column(name = "view_count", nullable = false)
private int viewCount;
#Column(name = "capture_date", nullable = false)
private Date captureDate;
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(name = "photo_metadata")
#MapKeyColumn(name = "metadata_name")
#Column(name = "metadata_value")
private Map<String, String> photoMetadata;
#ManyToMany
#JoinTable(name = "photo_keywords",
joinColumns = #JoinColumn(name = "keyword_id"),
inverseJoinColumns = #JoinColumn(name = "photo_id"))
public List<Keyword> keywords;
//getters and setters
}
This creates a join table photo_keywords, rather than a JoinColumn.
What I've tried so far with the Keyword entity:
#NamedQueries({
#NamedQuery(
name = "findKeywordByName",
query = "SELECT keyword from Keyword k WHERE k.keyword = :keyword"
)
})
which is executed via
public Keyword findKeywordByString(String keyword){
Keyword thisKeyword;
Query queryKeywordExistsByName = getEntityManager().createNamedQuery("findKeywordByName");
queryKeywordExistsByName.setParameter("keyword", keyword);
try {
thisKeyword = new Keyword((String) queryKeywordExistsByName.getSingleResult());
} catch (NoResultException e){
thisKeyword = null;
}
return thisKeyword;
}
This returns the Keyword, but with the photos property being null. This is to be expected, since I'm only selecting the keyword property. How can I adapt the SQL query above to a #NamedQuery?

How many indexes should be created for faster queries

My object model is given below and would like your inputs on the number of indexes to create for faster query responses (on h2, mysql). Assumptions and questions are given below the following model.
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false, insertable = false, updatable = false)
private Integer id;
#ManyToOne(fetch = FetchType.LAZY)
#ForeignKey(name = "fk_user_org_id")
#Index(name = "idx_user_org_id")
#JoinColumn(name = "org_id", nullable = false, referencedColumnName = "id")
#NotNull
private Organization organization;
#ManyToOne(fetch = FetchType.LAZY)
#ForeignKey(name = "fk_user_year_id")
#Index(name = "idx_user_year_id")
#JoinColumn(name = "year", nullable = false, referencedColumnName = "id")
#NotNull
private Year year;
#ManyToOne(fetch = FetchType.LAZY)
#ForeignKey(name = "fk_user_created_by")
#Index(name = "idx_user_created_by")
#JoinColumn(name = "created_by", nullable = false, referencedColumnName = "id")
#NotNull
private User createdBy;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "desc")
private String desc;
#Column(name = "is_system", length = LEN_1)
#Type(type = "org.hibernate.type.YesNoType")
private boolean isSystem = false;
#Column(name = "user_type", nullable = false)
private UserType userType;
#Column(name = "status", nullable = false)
#NotNull
private Status status;
}
Our plan is to use multi column indexes instead of a single column index (i.e. create index user_idx based on (organization, year, isSystem, status, userType, createdBy)). Assuming I have this index, will I get optimized responses for my queries listed below.
select * from user where organization=1 and year=2010;
select * from user where organization=1 and year=2010 and isSytem=true or false; (i.e. system users or application defined users)
select * from user where organization=1 and year=2010 and isSytem=false and userType=Manager (i.e. all managers)
select * from user where organization=1 and year=2010 and isSytem=false and userType=Employee (i.e. all employees)
select * from user where organization=1 and year=2010 and isSytem=false and userType=Manager and status=ACTIVE (i.e. Active users)
select * from user where organization=1 and year=2010 and createdBy='Sam' or 'Joe'
Does [6] need a different multi column index, consisting of the above 3 columns?
Since we are creating a multi column index as per my original assumption, can I safely remove the individual indexes (idx_user_org_id, idx_user_year_id, idx_user_created_by) as currently defined in the model?
You should switch the order of the columns in your index:
(organization, year, isSystem, userType, status, createdBy)
This allows it to better serve these two queries:
select * from user where organization=1 and year=2010 and isSystem=false and userType=Manager
select * from user where organization=1 and year=2010 and isSystem=false and userType=Employee
Does [6] need a different multi column index, consisting of the above 3 columns?
It doesn't need a new index - it can use the existing one but in a less efficient way - only the first two columns will be used. Adding a new index for this query looks like a good idea though.
can I safely remove the individual indexes
Yes. You should remove unused indexes otherwise they will just take up disk space and slow down table modifications without providing any benefit.