Open damianszczepanik opened 9 years ago
The generated DogBuilder already has full support for all Animal attributes.
You do not need to make DogBuilder an extension of AnimalBuilder.
Example:
@GeneratePojoBuilder
public class Animal {
public Date dateOfBirth;
}
@GeneratePojoBuilder
public class Dog extends Animal {
public String name;
}
Dog dog = new DogBuilder().withName("Lassie").withDateOfBirth( new Date()).build();
Btw, if Animal is abstract, just remove the annotation from Animal:
Example:
public abstract class Animal {
public Date dateOfBirth;
}
@GeneratePojoBuilder
public class Dog extends Animal {
public String name;
}
You still have full support of all Animal properties in DogBuilder:
Dog dog = new DogBuilder().withName("Lassie").withDateOfBirth( new Date()).build();
That makes sense but when I was trying to annotate like this I found that DogBuilder does not have withDateOfBirth and it does not extend Animal. Will check it again.
Does DogBuilder implement withDateOfBrith out of the box or some flag needs to be set?
The DogBuilder will not extend any other builder. But it will have with-methods for all accessible properties of the produced pojo, regardless of the point of declaration in the pojo's class hierarchy,
OK, finally I found that several fields have protected access and we use org.springframework.test.util.ReflectionTestUtils;.setField(dog, "id", id);
to set this field in builder. Giving public access for id
might not be good idea (usually.
Can I do this with pojobuilder? Any plan for this? Maybe not with spring which might be to heavy for this but some other library or pure Java...
PojoBuilder can access protected fields by default, if it's generated into the pojo's package.
If you want to access private fields, you could write some factory method to do it, and annotate it instead of the pojo.
Factory sounds good for this case. However the best of this tool is that I don't need to write any class/factory/method and adding new builder = add annotation.
I'm not sure if the factory is good solution for class hierarchy. Two, having factory for class or two is acceptable but not for more than 20-40 classes. Three I'm worry about maintaining those factories if new private field will be added to abstract Animal because then Dog, Cat, Bird... have to be updated as well.
Those builders are perfect and very comfortable as long as they support all fields from whole class hierarchy. Out of the box...
This is what I do when I want to generate a builder for a JPA-Bean that has a private ID field:
@Entity
@Table(name = "Article")
@SequenceGenerator(name = "seq-art", sequenceName = "SEQ_ART")
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq-art")
@Column(name = "ARTICEL_ID", nullable = false)
private Long id;
@Column(name = "NAME", nullable = false)
private String name;
@GeneratePojoBuilder // <-- annotate the constructor!
protected Article(Long id) {
this.id = id; // <-- initialization of private fields is done by the constructor
}
public Article() {
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I really like the idea of creating a builder class hierarchy, but it does not allow for exclusion of superclass fields wich is currently possible and might be important for #112. If we ignore that we would need to overwrite all with methods of the builder super class to return the correct self type (this is probably better than using a self generic like in assertj). If this is implemented it might be necessary to always generate builders for all superclasses of each pojoclass to make sure that all common ancestor builders are reused.
Builder for an abstract pojo is itself abstract
, probably closes this issue
Case is similar to #98 but this time I want to have full support for Dog builder which should also have access to Animal attributes.
To make it happen I declared builder for Animal (
AnimalBuilder
) and for Dog I declared following builder:but because Animal s abstract following
build()
method inAnimal
class won't compile:So the simplest way is to not create
build()
method for abstract classes. It has no sense and it won't compile.