JPQL query help: many-to-many relationship filtered by a collection - jpql

I'm having trouble writing a query using JPQL. I have two entities with a many-to-many relationship:
Entity1 (User)
#Entity
public class User implements Serializable {
#Id
private long id;
private String name;
#ManyToMany()
#JoinTable(name="users_roles",
joinColumns=#JoinColumn(name="user_id"),
inverseJoinColumns=#JoinColumn(name="role_id"))
private Set<Role> roles;
}
Entity2 (Role)
#Entity
public class Role implements Serializable {
#Id
private long id;
private String name;
}
Imagine that I have a list of roles that can vary in size (e.g. "roleA", "roleB", "roleC", ...), and I want to get every user that has every role in this list. In my head, it would be something like this:
select u from users u where :roles member of u.roles
As far as I know this doesn't work because :roles can't be a collection when used at the left hand side of "member of". Is there a way to achieve this in one JPQL query? If it is not possible in a single query, then what would be the best approach?
Thanks

Try this:
select u FROM User u JOIN u.roles r WHERE r IN (:roles)

Related

Spring data MongoDB GeoSpatial Distance

I trying to find the distances along with the locations by using Spring Data Mongo GeoSpatial.
Following this https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.geo-near
GeoResults<VenueWithDisField> = template.query(Venue.class)
.as(VenueWithDisField.class)
.near(NearQuery.near(new GeoJsonPoint(-73.99, 40.73), KILOMETERS))
.all();
I tried
#Data
#NoArgsConstructor
#AllArgsConstructor
public class RestaurantWithDisField {
private Restaurant restaurant;
private Number dis;
}
#Data
#AllArgsConstructor
#NoArgsConstructor
#Document(collection = "restaurants")
public class Restaurant {
#Id
private String id;
private String name;
#GeoSpatialIndexed(name = "location", type = GeoSpatialIndexType.GEO_2DSPHERE)
private GeoJsonPoint location;
}
public GeoResults<RestaurantWithDisField> findRestaurantsNear(GeoJsonPoint point, Distance distance) {
final NearQuery nearQuery = NearQuery.near(point)
.maxDistance(distance)
.spherical(true);
return mongoTemplate.query(Restaurant.class)
.as(RestaurantWithDisField.class)
.near(nearQuery)
.all();
}
But in the result I am getting the below. If I don't set the target type and just collect the domain type I get all the other values but the distance.
Restaurant - RestaurantWithDisField(restaurant=null, dis=0.12914248082237584
Restaurant - RestaurantWithDisField(restaurant=null, dis=0.19842138954997746)
Restaurant - RestaurantWithDisField(restaurant=null, dis=0.20019522190348576)
Can someone please help me why I am unable to fetch the domain type value or how should I?
Thank you
The mapping fails to resolve restaurant in RestaurantWithDisField because the values within the result Document do not match the target entities properties.
You might want to use inheritance instead of composition here and let RestaurantWithDisField extend Restaurant, provide your own converter or just use Restaurant and rely on GeoResults holding a list of GeoResult that already include the Distance along with the actual mapped domain type - pretty much the same, that you've be modelling with RestaurantWithDisField.
Spring Data Mongo repository can generate the right query for you if you name it correctly and put the data into your domain POJO. I was able to find examples here - blocking or here - reactive.
interface RestaurantRepository extends MongoRepository<Restaurant, String> {
Collection<GeoResult<Restaurant>> findByName(String name, Point location);
}
From what I see, the (Reactive)MongoTemplate uses a GeoNearResultDocumentCallback to wrap the restaurant in a GeoResult. You may want to take a look there.

How to use UserDefinedType(UDT) with Spring Data Cassandra for List<UDT>

I have created a UDT named widgetData in cql for which i have a corresponding POJO class named widgetData. I want to use this in another domain POJO class as List. What kind of annotation should be used to do so?
#Table("dashboardManagement")
public class Dashboard implements Serializable {
#Column("dashboardState")
#CassandraType(type = DataType.Name.UDT, userTypeName = "widgetData")
private List<widgetData> dashboardState;
....
The above code does not work.
Do I have to write a seperate userTypeResolver for this?
I realize this question is a little old, but I have made this work.
Basically, I had a user profile with an address UDT, and that UDT had its own POJOs/entity classes. The UDT address entity class used the #UserDefinedType annotation:
#UserDefinedType("address")
public class AddressEntity implements Serializable {
private static final long serialVersionUID = 1817053316281666003L;
#Column("mailto_name")
private String mailtoName;
private String street;
private String street2;
private String city;
...
The user entity utilized the Address UDT entity:
#Table("user")
public class UserEntity implements Serializable {
private static final long serialVersionUID = 4067531918643498429L;
#PrimaryKey("user_id")
private UUID userId;
#Column("user_email")
private String userEmail;
#Column("first_name")
private String firstName;
#Column("last_name")
private String lastName;
#Column("addresses")
private List<AddressEntity> addresses;
...
Then, it was a simple matter to map a user's address data to a UserEntity object (userE below) and save it with standard repository methods.
// save to DB
userRepo.save(userE);
You can find everything built to support the User services here: https://github.com/datastaxdevs/workshop-ecommerce-app/blob/main/backend/src/main/java/com/datastax/tutorials/service/user/
So I would say to have a look at the class for the widgetData object, make sure it's using the #UserDefinedType annotation, and mark the column using the #Column annotation in the Dashboard class (basically, get rid of the #CassandraType):
#Column("dashboardState")
private List<WidgetData> dashboardState;

How to save inherited class using astyanax?

I am unable to save child class data with the persistence of parent class using astyanax in cassandra.
I created the child object with all necessary data, but when I try to store that object, only values from the parent class is stored, not from child object.
Here is the sample Code not real:
#Entity
class Shape{
#Id
private String id;
#Column
private String name;
}
#Entity
class square extends Shape{
#column
private int width;
}
now to store I am using EntityManager of astyanax.
square s=new square();
s.setName("sqaure");
s.setWidth(100);
s.setId("1234");
EntityManager em= //initialization code
em.put(s);
after doing this only "name" and "id" is stored into database. not width.
The EntityManager requires the type of the entity via the withEntityType() method. This type is used to build an EntityMapper via reflection which then determines the fields to serialize. There is nothing in the Entity persistence documentation or examples that says Astyanax supports polymorphism. This is not a bug, just a feature that doesn't exist. You will need a type-specific EntityManager for each subtype of your base class.

JPA and JSF Datatable Optimization

I need to display a large table with about 1300 roles at one time. (I know I should use a data scroll but my users want to see the whole table at one time.) The table displays 4 columns. Two of those columns are from the object but the other two are from referenced objects in the original object. I need to find the best/efficient way to do this. I currently have this working but when I reload the table it give an out of memory error. I think that it's caused by the large amount of redundant data in memory.
Create a view object that the repository will fill in only the needed fields.
Any other suggestions.
Here are the objects:
public class Database extends EntityObject {
private Long id;
private String name;
private String connectionString;
private String username;
private String password;
private String description;
// getter and setters omitted
}
public class Application extends EntityObject {
private Long id;
private String name;
private String fullName = "";
private String description;
private Database database;
private List<Role> roles = new ArrayList<Role>(0);
// getter and setters omitted
}
public class Role extends EntityObject {
private Long id;
private String name;
private String nameOnDatabase;
private Application application;
// getter and setters omitted
}
What I need displayed from the list of Roles is:
role.id, role.name, role.application.name, role.application.database.name
To optimize wisely, define what are you going to do with data, view or/and edit. Here are some common scenarios:
Retrieval using lazy fetch type.
Mark your roles in application with FetchType.LAZY annotation.
Retrieval using multiselect query. Create your custom class (like DTO) and populate it with data from the database using multiselect query. (Similar to VIEW mapped as Entity)
There are also other possibilities, such as Shared (L2) Entity Cache or Retrieval by Refresh.
See if you are using EntityManager correctly reading Am I supposed to call EntityManager.clear() often to avoid memory leaks?.

Do we really need Automapper?

I was learning AutoMapper and understand its use for object to object mapping. But now EFCodeFirst,dapper and Petpoco all cools stuff are there which will allow us to use our POCO directly with database?
So can anybody let me know why we still need automapper?
Thanks in advance
Best Regards,
Jalpesh
I usually use Automapper to map Domain models to view mdoels. If doing DDD it is often suggested that it's not a great idea to use your Domain models in you views - views often have a different set of concerns to the domain.
For example, you may have a User model in your domain:
public class User
{
public int Id {get;set;}
public string EmailAddress {get;set;}
public string FirstName {get;set;}
public string Surname {get;set;}
public string HashedPassword {get;set;}
public string EyeColour {get;set;}
}
And you may have a User summary page which shows a subset of these items:
public class UserSummary
{
public string EmailAddress {get;set;}
public string Surname {get;set;}
}
You could use the UserSummary class on the view, but you would probably fetch the domain user model from the db. In this case you could use Automapper to map the Domain.User to the ViewModel.UserSummary
var user = _repository.Get(1);
var viewmodel = Automapper.Map<Domain.User, ViewModel.UserSummary>(user);
return View(viewmodel);

Resources