I have two serializable classes of which the first, Main, includes members Id, and Details, an enumeration of the second class, Detail.
Eg
<DataContract()>
Class [Main]
<DataMember(Name:="id")>
Property [Id] As Integer = 0
<DataMember(Name:="details")>
Property [Details] As IEnumerable(Of [Detail]) = Nothing
End Class
<DataContract()>
Class [Detail]
<DataMember(Name:="name")>
Property [Name] As String = Nothing
<DataMember(Name:="dob")>
Property [BirthDate] As Date? = Nothing
End Class
(This is a very simplified example so please don't ask why I want to do this.)
What I want to end up with is just, Details, the collection of Detail, BUT with the Id property from the parent, Main, included.
So ...
Id = 1, Name = "John Smith", BirthDate = #1/1/1990#
Id = 1, Name = "Jane Jones", BirthDate = #2/2/1990#
Id = 2, Name = "Jim Hicks", BirthDate = #3/3/1990#
Id = 3, Name = "Jana Walsh", BirthDate = #4/4/1990#
Id = 3, Name = "Jason Brown", BirthDate = #5/5/1990#
Now, I know I could simply iterate through the results and copy Id from the Main object to the Detail objects. But is there a way of adding Id to Detail objects via the serialization process? (Sorry if I have some nomenclature wrong here re serialization, etc.)
Note: I can't - or don't want to - make Detail a child class of Main because Detail is re-used in other classes.
Related
I have a .net webapi endpoint that currently returns an array of objects (JSON).
I'm trying to group the items by the created date, but i can't work out the LINQ statement to achieve this.
Class:
Public Class mImage
Public Property fileName As String
Public Property id As Guid
Public Property description As String
Public Property createDate As DateTime
End Class
Public Class mImageParent
Public Property groupDate As DateTime
Public Property images As List(Of mImage)
Public Property groupCount As Integer
End Class
My current JSON return looks like this:
obj: [
{"fileName":"a","id":"1","createDate":"1-1-2020"},
{"fileName":"b","id":"2","createDate":"1-1-2020"},
{"fileName":"c","id":"3","createDate":"2-1-2020"}
]
Where i'm trying to return it as:
obj: {"groupDate":"1-1-2020",
"images": [
{"fileName":"a","id":"1","createDate":"1-1-2020"},
{"fileName":"b","id":"2","createDate":"1-1-2020"}
]},
{"groupDate":"2-1-2020",
"images": [
{"fileName":"c","id":"3","createDate":"2-1-2020"}
]}
Current Code that just selects without grouping LINQ(vb.net):
Dim imageResult = (From p In db.file_images Where p.user_id = userIdParam).ToList()
For each p in imageResult
mImageList.Add(New mImage With {.id = p.image_id, .description = p.image_desc, .fileName = p.image_file, .createDate= p.create_timestamp})
Next
I can't sort out how to select into groups. The for..each is required because some other stuff goes on before the item is added to the list.
The syntax i have (not working, can't work out the select into):
Dim imageResultGroup = (From p in db.file_images where p.user_id = userIDParam).GroupBy(Function(g) g.create_timestamp).Select(Function(grp) New mImageParent with {.groupDate = grp.Key, images = grp.ToList()})
The following method will return an anonymous object that has the following properties:
createdDate - the grouped on date
images - a collection of mImage
VB.Net Code:
Dim groupedImages =
From fileImage As mImage In fileImages
Select fileImage
Group By createdDate = fileImage.createDate
Into images = Group
Order By createdDate
With a little refactoring, you can rename the createdDate property to groupDate.
I've read the docs and searched this site but cannot seem to find a solution to sorting field values by the order in which they are declared. The docs state that adding ordered = True to the class Meta will solve this problem -
class MySchema(Schema):
class Meta:
ordered = True
However, I am not using class Meta in my schema. My schema simply looks like -
class MySchema(Schema):
id = fields.Integer()
name = fields.Str()
category = fields.Str()
So in this situation, how and where would I set ordered = True? Thanks!
I solved the issue by changing my schema class to -
class MySchema(Schema):
class Meta:
ordered = True
id = fields.Integer()
name = fields.Str()
category = fields.Str()
and then also adding JSON_SORT_KEYS=False to my app's config.py file.
I have 2 database tables Customer and Items with 1 -> many relation. To fetch data from database i am using the following query.
select customer.id, customer.name, items.itemName, items.itemPrice from testdb.customer INNER JOIN items ON items.customer_Id = customer.id
I have an entity class Customers
#Entity
public class Customer{
#Id
private int id;
#Column
private String name;
#Column
private String itemName;
#Column
private int itemPrice;
public Customer() {}
//Getter and setter are here
.......
}
in Service class i have the following code.
#GET #Path("/getCustomerInfo")
#Produces(MediaType.APPLICATION_JSON)
public List getCustomerInfo() {
CustomerDao dao = new CustomerDao();
return dao.getBuildingsCustomerInfo();
}
in my DAO class i have the following code
public List<Customer> getCustomerInfo(){
Session session = SessionUtil.getSession();
String queryString = "the above mentioned query";
List<Customer> customerInfo = session.createNativeQuery(queryString, Customer.class) ;
session.close();
return customerInfo;
}
I am getting the following JSON response from the service
[id:1, name:"Alfred", itemName:"jeans", itemprice:10],[id:1, name:"Alfred", itemName:"jeans", itemprice:10],[id:2, name:"James", itemName:"watch", itemPrice:20 ],[id:2, name:"James", itemName:"watch", itemPrice:20 ], [id:2, name:"James", itemName:"watch", itemPrice:20 ]
The number of results are 5 which is correct But 2nd result is a copy of 1st, 4th and 5th are copies of 3rd. In 2nd, 4th and 5th results the itemName and the itemPrice should be different.
if I use createSQLQuery(queryString); instead of createNativeQuery(queryString, Customer.class); I am getting the correct result but without entity attribut names.
[1, "Alfred", "jeans", 10],[1, "Alfred", "shirt", 15],[2, "James", "watch", 20], [2, "James", "coffee", 25], [2, "James", "drinks", 30]
I have seen number of articles but could not find the solution. I have to use createNativeQuery() not createSQLQuery() because I need to map the entity class attributes. Please let me know if i am doing something wrong.
Your data structure is wrong on the Java side and not corresponding to the database relation. In the relation you describe you need to have a list of items:
#Entity
public class Customer implements Serializable {
// ... the fields you have so far
// assuming the parent field on the other side is called customer
// you may also want to set the cascade and orphanRemoval properties of the annotation
#OneToMany(mappedBy = "customer")
#JsonManagedReference // assuming you're using Jackson databind JSON
private List<Item> items;
}
And on the Item side:
#Entity
public class Item implements Serializable {
#Id
private int id;
#JsonBackReference
#ManyToOne
#JoinColumn(name = "customer_Id")
private Customer customer;
}
Then if you really the JSON data strucutred that way, you need a third Entity class to use as a ResultSetMapping.
#Entity
#SqlResultSetMapping(
name = "CustomerItem",
entities = #EntityResult(entityClass = CustomerItem.class)
)
#NamedNativeQueries({
#NamedNativeQuery(
name = "CustomerItem.getAll",
resultSetMapping = "CustomerItem"
query = "select customer.id as cid, items.id as iid, customer.name,"
+ " items.itemName, items.itemPrice from testdb.customer INNER JOIN"
+ " items ON items.customer_Id = customer.id"
)
})
public class CustomerItem implements Serializable {
#Id
private int cid;
#Id
private int iid;
#Column
private String name;
#Column
private String itemName;
#Column
private int itemPrice;
... getters and setters
}
Then you can use the native query in named variant, which should offer some slight optimizations.
List<CustomerItem> lst = em.createNamedQuery("CustomerItem.getAll", CustomerItem.class)
.getResultList();
The use of #SqlResultSetMapping is so that the returned entities are not monitored for changes, but you can still use the defined entity for the result. I believe that by JPA specification it should also work without it, but in Hibernate it doesn't. Could be a bug, or a planned, but not implemented feature, or I could just be misinterpreting the JPA usage, but this workaround does work with Hibernate 5+.
Not sure about the exact reason behind duplicates but SELECT DISTINCT will solve your issue as it will take only distinct records.
Refer using-distinct-in-jpa
I solve this issue by using #SqlResultSetMapping
I have two tables
class student(models.Model):
frist_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
class subject(models.Model):
student = models.ForeignKey(student)
sub_name = models.CharField()
I want student list and subject count in serializer
my serializer
classs SubjectSerializers(serializers.ModelSerializer):
class Meta:
model = JobPosting
fields = ('id','sub_name')
class StudentSerializers(serializers.ModelSerializer):
sub = SubjectSerializers(source = 'student')
class Meta:
model = JobPosting
fields = ('id','first_name', 'last_name','sub')
How can i get subject count for every student in serializer, Now i am geting subject table data but i want count like this
"detail": [{
"id": 680,
"first_name": "riya",
"last_name": "tri",
"subject_count": 5
}],
You can achieve this by using a serializer method field
Then StudentSerializer becomes the following:
class StudentSerializers(serializers.ModelSerializer):
sub = SubjectSerializers(source = 'student')
subject_count = serializers.SerializerMethodField()
class Meta:
model = JobPosting
fields = ('id','first_name', 'last_name','sub')
def get_subject_count(self, student):
return Subject.objects.filter(student=student).count()
If I have
Category()
products = db.relationship('Product', backref='category')
name = Column(String())
Product()
name = Column(String())
category_id = Column(Integer(), ForiegnKey('category.id')
When I do
Product.query.join(Category).options(contains_eager(Product.category)).all()
I'd like to end up with a list of Products that have a 'pseudo' (or transient in ORM parlance) category_name field populated, so I don't have to interrogate the category like this
product.category.name
and can do this instead
product.category_name
Thanks
You can do this with association proxies:
class Product(Base):
...
category_name = association_proxy("category", "name")