Do I have to create both getter and setter for a field? - flutter

Say I have a class like this :
class Product {
int id;
Product([this.id]);
}
And I allow my product id to be changed. So, am I good with above or should I use below model
class Product {
String _id;
Product([this._id]);
set id(id) => _id = id; // setter
get id => _id; // getter
}

It depends on the use of you class, for instance if the class is a model class for instance
(Employee class)which is only used to save some data and no functionality,
then it should include a setter and getter for its member variables.
But if there is service layer class, which uses Employee class and performs certain operations on it, then use of setter and getter is not a must.

Getters and setters are created automatically for non-private class instance variables. So your top code is fine for reading and updating the id variable from anywhere.

Related

How to query using fields of subclasses for Spring data repository

Here is my entity class:
public class User {
#Id
UserIdentifier userIdentifier;
String name;
}
public class UserIdentifier {
String ssn;
String id;
}
Here is what I am trying to do:
public interface UserRepository extends MongoRepository<User, UserIdentifier>
{
User findBySsn(String ssn);
}
I get an exception message (runtime) saying:
No property ssn found on User!
How can I implement/declare such a query?
According to Spring Data Repositories reference:
Property expressions can refer only to a direct property of the managed entity, as shown in the preceding example. At query creation time you already make sure that the parsed property is a property of the managed domain class. However, you can also define constraints by traversing nested properties.
So, instead of
User findBySsn(String ssn);
the following worked (in my example):
User findByUserIdentifierSsn(String ssn);

kotlin data class + bean validation jsr 303

I'm trying to get Kotlin working with jsr 303 validation on a spring-data-rest project.
Given the following data class declarartion :
#Entity data class User(
#Id
#GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
var id: Long? = null,
#Size(min=5, max=15)
val name: String
)
The #Size annotation has no effect here, making me able to save a user with a name of 1 character.
It works well when executing the very same example but in a Java class instead of Kotlin.
This makes me think of a Kotlin problem.
Thanks in advance for you help !
You need to use Annotation use-site targets since the default for a property declared in the constructor is to target the annotation on the constructor parameter instead of the getter (which will be seen by JavaBeans compliant hosts) when there are multiple options available. Also using a data class might be inappropriate here (see note at end).
#Entity data class User(
#Id
#GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
var id: Long? = null,
#get:Size(min=5, max=15) // added annotation use-site target here
val name: String
)
The property target from the Kotlin docs may look tempting, but it can only be seen from Kotlin and not Java. Usually get does the trick, and it is not needed on the bean set.
The docs describe the process as:
If you don’t specify a use-site target, the target is chosen according to the #Target annotation of the annotation being used. If there are multiple applicable targets, the first applicable target from the following list is used:
param
property
field
And the #Size annotation is:
#Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
Therefore since PARAMETER is a valid target, and multiple targets are available (parameter, field, method [get/set]) it choses PARAMETER which is not what you want. Therefore for a JavaBean host to see the property it will look for the getter (properties are defined by the getter/setter and not the backing field).
In one of the Java samples, it shows:
public class Book {
private String title;
private String description;
// ...
#NotEmpty(groups={FirstLevelCheck.class, Default.class})
#Size(max=30)
public String getTitle() {
return title;
}
// ...
}
Which matches our usage of having it on the getter. If it were to be on the field like some of the validation annotations show, see the field use-site target. Or if the field must also be publicly accessible, see the #JvmField annotation in Kotlin.
NOTE: As mentioned in notes from others, you should likely consider NOT using a data class for entities if they use an auto-generated ID since it will not exist for new objects the same as for retrieved objects; and a data class will generate equals and hashCode to include all fields including the ones it should not. You can read guidance about this from the Hibernate docs.
Use the #get or #field targets for validation annotations. Annotations with the target #param(first default) and #property are not supported.
e.g:
From #NotEmpty To #field:NotEmpty
data class Student(
#field:NotEmpty #field:Size(min= 2, message = "Invalid field") var name: String? = ""
)
GL
Jayson Minard
Annotation use site targets

Null pointer when using QueryDSL subtypes

I am trying to create a subtype query along the following lines, but tyre is coming back as null even if I set #QueryInit("tyre") on the wheel property of car.
QWheel wheel = QCar.car.wheel;
QTyre tyre = wheel.as(QRoadWheel.class).tyre;
BooleanExpression tyreFittedOverYearAgo
= tyre.fitted.lt(today.minusYears(1));
Iterable<Car> carsWithOldTyres = repo.findAll(tyreFittedOverYearAgo);
How do I get QueryDSL to initialise tyre when it is accessed using as()?
By default Querydsl initializes only direct reference properties. In cases where longer initialization paths are required, these have to be annotated in the domain types via com.mysema.query.annotations.QueryInit usage. QueryInit is used on properties where deep initializations are needed.
#Entity
class Event {
#QueryInit("customer")
Account account;
}
#Entity
class Account{
Customer customer;
}
#Entity
class Customer{
String name;
String address;
}
This will intialize customer.name ,customer.address
I've not been able to establish why, but I've now got things working but by using:
#QueryInit("*")
Tyre tyre;

Entity framework code first and data annotaions

I use code first approach in my project. In the prject I have classes with MetadataType attribute, which I don't use in my EF model. Class with metadata has some constant public fields (in addition to fields from main type). Now when I tried to query EF it threw exception that in metadata class there fields not mapped... se below in details
class M1
{
int Id;
string Name
}
class M2
{
int Id;
DateTime Date
}
[MetadataType(typeof(PageOFSRevenueMetadata))]
class NotRelatedToModel
{
int Prop1;
int Prop2;
}
class PageOFSRevenueMetadata
{
public const string RuleSet1 = "r1";
public const string RuleSet2 = "r2";
// Data Vaidation Attrs...
int Prop1;
int Prop2;
}
In my context I have mapping only for M1 and M2. In the DB exists table with name 'NotRelatedToModel', but I don't want to use it in my model. I use EF 6
Now when I try to make join query on M1 and M2 it threw below exception
'NotRelatedToModel' contains the following unknown properties or fields: RuleSet1, RuleSet2. Please make sure that the names of these members match the names of the properties on the main type
I can move this static fields to another place and it seems to work, but I would like to know why it is happend ? How the EF code first mapping works ?
Thanks in advance

How to solve field wrapping in Entity Framework database-first

When I use database first, after creating the edmx file, all the conceptual models have already been generated. But I want to do some special operations on certain fields. For example, there's a field named 'price'; I want the matching property 'Price' to return double of the 'price'. How can I do that? If I modify the getter in the code, every time I update the model from database, all of the modifications go away.
What's the correct way to do this?
What you can do is create a partial class for entity which contains the Price Property and put a getter like this (A property with double price will be meaningful ),
Public partial class YourEntity{
Public float DoublePrice{
get { return Price*2;}
}
}
Or you can create a class inherited from the entity,
Public partial class Entity:YourEntity{
Public override float Price{
get { return base.Price*2;}
}
}