? He leído que es útil usar el patrón de generador cuando se tiene una clase con muchos parámetros. Me pregunto cómo puedes implementar una entidad usando un patrón de generador. Sería genial si puedes proporcionar un código de muestra.¿Cómo se puede utilizar el patrón de generador para las entidades con JPA
Respuesta
Por supuesto, es posible, solo tiene que proporcionar un Constructor (posiblemente anidado) para cada Entidad.
Aquí es un ejemplo de trabajo:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class FluentEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String someName;
private int someNumber;
private boolean someFlag;
protected FluentEntity(){}
private FluentEntity(String someName, int someNumber, boolean someFlag) {
this.someName = someName;
this.someNumber = someNumber;
this.someFlag = someFlag;
}
public long getId() {
return id;
}
public String getSomeName() {
return someName;
}
public int getSomeNumber() {
return someNumber;
}
public boolean isSomeFlag() {
return someFlag;
}
public static FluentEntityBuilder builder() {
return new FluentEntityBuilder();
}
public static class FluentEntityBuilder {
private String someName;
private int someNumber;
private boolean someFlag;
public FluentEntityBuilder setSomeName(final String someName) {
this.someName = someName;
return this;
}
public FluentEntityBuilder setSomeNumber(final int someNumber) {
this.someNumber = someNumber;
return this;
}
public FluentEntityBuilder setSomeFlag(final boolean someFlag) {
this.someFlag = someFlag;
return this;
}
public FluentEntity build() {
return new FluentEntity(someName, someNumber, someFlag);
}
}
}
El código para utilizar sería la siguiente:
FluentEntity entity = FluentEntity.builder().setSomeName(someName).setSomeNumber(someNumber)
.setSomeFlag(someFlag).build();
Hemos de tener en cuenta que hay que excluir a los campos generados automáticamente como la clave principal (en este caso de ejemplo, el id
) si tiene alguno.
Si desea deshacerse del código "estándar" para crear clases de Generador para cada Entidad, recomendaría una biblioteca de conveniencia, algo así como lombok. Luego obtendrá sus constructores (y aún más) anotando sus Entidades, tal vez cuesta un poco más de trabajo excluir los campos de id.
Usted debe echar un vistazo a Project Lombok
Sin embargo, he aquí algo de código para probar este constructor (implementado con Spring e Hibernate Boot).
El repositorio:
import org.springframework.data.repository.CrudRepository;
import com.example.model.FluentEntity;
public interface FluentEntityRepository extends CrudRepository<FluentEntity, Long> {
}
Y aquí hay algunas pruebas:
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
import java.util.stream.StreamSupport;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import com.example.model.FluentEntity;
@RunWith(SpringRunner.class)
@Transactional
@SpringBootTest
public class FluentEntityRepositoryTests {
@Autowired
private FluentEntityRepository fluentEntityRepository;
@Test
public void insertAndReceiveFluentEntityCreatedWithBuilder() {
final String someName = "name";
final int someNumber = 1;
final boolean someFlag = true;
FluentEntity entity = FluentEntity.builder().setSomeName(someName).setSomeNumber(someNumber)
.setSomeFlag(someFlag).build();
entity = fluentEntityRepository.save(entity);
assertThat("Entity did not get an generated Id!", entity.getId(), greaterThan(-1L));
assertThat("Entity name did not match!", entity.getSomeName(), is(someName));
assertThat("Entity number did not match!", entity.getSomeNumber(), is(someNumber));
assertThat("Entity flag did not match!", entity.isSomeFlag(), is(someFlag));
}
@Test
public void insertSomeAndReceiveFirst() {
fluentEntityRepository.save(FluentEntity.builder().setSomeName("A").setSomeNumber(1).setSomeFlag(true).build());
fluentEntityRepository
.save(FluentEntity.builder().setSomeName("B").setSomeNumber(2).setSomeFlag(false).build());
fluentEntityRepository.save(FluentEntity.builder().setSomeName("C").setSomeNumber(3).setSomeFlag(true).build());
final Iterable<FluentEntity> findAll = fluentEntityRepository.findAll();
assertThat("Should get some iterable!", findAll, notNullValue());
final FluentEntity fluentEntity = StreamSupport.stream(findAll.spliterator(), false).findFirst().get();
assertThat("Should get some entity!", fluentEntity, notNullValue());
}
}
¿El marco JPA podrá "automáticamente" ('@ Autowire'?) Crear instancias de Entidades que tengan instaladores solo en el constructor? –
No sé si recibí su pregunta, pero en general los incubadores no son necesarios si se utiliza el acceso de campo. Entonces el proveedor JPA no invoca a los instaladores y los constructores pueden ser suficientes para su código comercial. Consulte "2.2 Campos y propiedades persistentes" en: http://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf –
Ok, pero la razón principal por la que quiero usar un constructor es para que pueda crear campos 'finales'. Si usa el acceso de campo, no puede hacer que sean definitivas, ¿verdad? –
- 1. Patrón de generador con herencia
- 2. Cómo usar el generador de entidades poco
- 3. Posible tener entidades JPA inmutables?
- 4. Seleccionar no entidades con JPA?
- 5. JPA: Ideas para rastrear la evolución/cambios de las entidades
- 6. Cómo persistir muchas entidades (JPA)
- 7. Guardando muchas entidades en GAE con JPA
- 8. Patrón de generador y persistencia
- 9. JPA 2 XML Asignación de incrustado para que funcione con el generador de modelo Hibernate Meta
- 10. Entidades JPA y/vs DTOs
- 11. Cómo utilizar el patrón de visitante para sustituir "instanceof"
- 12. DDL de ingeniero inverso de entidades JPA
- 13. Cómo implementar entidades JPA polimórficas con relaciones genéricas
- 14. No se puede configurar JPA con ehcache
- 15. Sin autodetección de las entidades JPA en maven-verify
- 16. JPA CriteriaBuilder - Cómo utilizar el operador de comparación "IN"
- 17. ¿Cómo se deben manejar las entidades padre e hijo en el patrón de repositorio?
- 18. ¿Se puede usar el generador XeLaTeX con Sphinx?
- 19. ¿Cómo utilizar la auditoría en JPA/Spring-Data JPA?
- 20. ¿Por qué usar el patrón de generador?
- 21. JPA: Extendiendo el contexto de persistencia frente a entidades desprendimiento
- 22. Primavera: uso de patrón de generador para crear un bean
- 23. Java genéricos + Generador patrón
- 24. Cómo que registre automáticamente entidades con JPA/Hibernate: entidad desconocida
- 25. ¿Patrón de diseño bueno para la historia de muchas entidades?
- 26. jpa lazy fetch entidades sobre múltiples niveles con criterios api
- 27. Protocolo de búferes con JPA
- 28. ¿Cuándo utilizar el patrón abstracto de fábrica?
- 29. 2 entidades JPA en la misma tabla
- 30. separan entidades JPA de Hibernate específica ajustes
por qué es importante que la clase es una entidad? ¿Por qué usar el patrón del generador para construir entidades es diferente de usarlo para construir cualquier otra cosa? –
Quiero que sea una entidad, para poder almacenarlo en db. –