JPA trying to remove entity - java

I'm using a method to save a object in database, see:
#Transactional(propagation = Propagation.REQUIRED)
public void movimentarCaixa(String descricao,
AbstractBean donoCaixa, FormaPagamento formaPagamento, HistoricoPagamento historicoPagamento, double valor) {
try {
HistoricoCaixa historicoCaixa;
if (donoCaixa instanceof Dentista) {
logger.info("Iniciando movimentacao caixa para Dentista. Valor: "+valor);
historicoCaixa = new HistoricoCaixaDentista();
((Dentista) donoCaixa).setCaixaSaldoAtual(((Dentista) donoCaixa).getCaixaSaldoAtual()
+ valor);
((HistoricoCaixaDentista) historicoCaixa).setDentista((Dentista) donoCaixa);
} else if (donoCaixa instanceof Paciente) {
logger.info("Iniciando movimentacao caixa para Paciente. Valor: "+valor);
historicoCaixa = new HistoricoCaixaPaciente();
((Paciente) donoCaixa).setCaixaSaldoAtual(((Paciente) donoCaixa).getCaixaSaldoAtual()
+ valor);
((HistoricoCaixaPaciente) historicoCaixa).setPaciente((Paciente) donoCaixa);
} else if (donoCaixa instanceof Clinica) {
logger.info("Iniciando movimentacao caixa para Clinica. Valor: "+valor);
historicoCaixa = new HistoricoCaixaClinica();
Clinica clinica = (Clinica) donoCaixa;
if (formaPagamento == null || formaPagamento.getCodigo().equals("DINHEIRO")){
clinica.setSaldoDinheiro(clinica.getSaldoDinheiro() + valor);
} else if (formaPagamento.getCodigo().equals("CHEQUE")) {
clinica.setSaldoCheque(clinica.getSaldoCheque() + valor);
} else if (formaPagamento.getCodigo().equals("DEBITO")) {
clinica.setSaldoDebito(clinica.getSaldoDebito() + valor);
} else if (formaPagamento.getCodigo().equals("CREDITO")) {
clinica.setSaldoCredito(clinica.getSaldoCredito() + valor);
}
((HistoricoCaixaClinica) historicoCaixa).setClinica((Clinica) donoCaixa);
} else {
throw new MyException(
"O parametro 'donoCaixa' deve ser do tipo Dentista, Paciente ou Clinica");
}
historicoCaixa.setDataHora(historicoPagamento.getDataHora());
historicoCaixa.setDescricao(descricao);
historicoCaixa.setFormaPagamento(formaPagamento);
historicoCaixa.setHistoricoPagamento(historicoPagamento);
historicoCaixa.setUsuario((Usuario) SessionContext.getInstance().getUsuarioLogado());
historicoCaixa.setValor(valor);
this.getDao().save(historicoCaixa);
} catch (Exception e) {
e.printStackTrace();
}
}
I call this method twice, in the first time the variable "historicoCaixa" receives "new HistoricoCaixaPaciente()" instance and in second time this same variable receives "new HistoricoCaixaClinica()". The problem is that in second call i got error:
Caused by: java.lang.IllegalArgumentException: Removing a detached instance br.com.odontonew.financeiro.bean.HistoricoCaixaClinica#94
I imagine that JPA is trying to remove HistoricoCaixaClinica#94 but i don't want this, how can i avoid it ?

Related

Losing value of variable

I'm doing a Login form using SQL Server and using three layer architecture, I debugged the project and basically it works like this: I put the user and password in the jframe, the user and pass are sent to the BL method and then to DA, when I put the user and pass correctly the Query is executed and "resultado" value is 1, then it goes back to the GUI but when its validated "getResultado" the value of "resultado" is 0, therefore I can't login.
This is my GUI method:
u.validarLogin(jtxtUsuario.getText(), String.valueOf(jpsfContrasenia.getPassword()));
if (admin.getResultado() == 1) {
new jfrmInterno().setVisible(true);
} else {
JOptionPane.showMessageDialog(null, "El nombre de usuario ingresado no coincide con ninguna cuenta", "", JOptionPane.ERROR_MESSAGE);
jtxtUsuario.setText("");
jpsfContrasenia.setText("");
}
}
This is my BL method:
public void validarLogin(String user, String pass) {
if (user != null && pass != null) {
admin.setUsuario(user, pass);
}else {
System.out.println("Incorrecto");
}
}
This is my DA method:
public int setUsuario(String user, String pass) {
this.getConexion();
String usuario = user;
String password = pass;
try {
Statement ejecutor = cn.createStatement();
ResultSet rs = ejecutor.executeQuery("SELECT * FROM [dbo].[Login] where NombreUsuario = '" + usuario + "' AND Contrasenia= '" + password + "'");
if (rs.next()) {
resultado = 1;
} else {
resultado = 0;
}
} catch (Exception e) {
}
return resultado;
}
public int getResultado() {
return resultado;
}
To simplify the code, do this;
1. Add a return type to your BL method
public int validarLogin(String user, String pass) {
int resultado = 0;
if (user != null && pass != null) {
resultado = admin.setUsuario(user, pass);
}else {
System.out.println("Incorrecto");
}
return resultado;
}
Then change your GUI method to this;
int resultado = u.validarLogin(jtxtUsuario.getText(), String.valueOf(jpsfContrasenia.getPassword()));
if (resultado == 1) {
new jfrmInterno().setVisible(true);
} else {
JOptionPane.showMessageDialog(null, "El nombre de usuario ingresado no coincide con ninguna cuenta", "", JOptionPane.ERROR_MESSAGE);
jtxtUsuario.setText("");
jpsfContrasenia.setText("");
}
}
This should definitely work as now you are returning the result as a variable every time validation BL method is being called.
Forgive me in case of any typos.

ResultSet only returns one row when more exist in the database

I created a java class called Executar_Query_Bd_Multiplos_Resultados in this class as the parameter for the Conectar method 2 values (int Integer1, int Integer2) of integer type.
These values are received by the query:
"SELECT DS_ESTRATEGY, STRID_ID" +
"FROM TB_BKOFFICE_ESTRATEGY" +
"WHERE IN_STRATEGY_ID IN (" + Istrategy1 + "," + Istrategy2 + ")";
The result of the above query is stored in the variable ls_command.
In the Executar_Query_Bd_Multiplos_Resultados_Test class I make the method call (Connect) and step 2 parameters (179, 319) and command to print on the screen the variable of type String codEstrategies.
But Eclipse only displays 1 result on the console. The query should bring 2 results and not 1. Here is the code for the Java classes and the result of the query executed in Oracle SQL Developer.
public class Executar_Query_Bd_Multiplos_Resultados_Test {
#Before
public void setUp() throws Exception {
Executar_Query_Bd_Multiplos_Resultados qr_2 = new Executar_Query_Bd_Multiplos_Resultados();
String codEstrategias = qr_2.Conectar(179, 319);
System.out.println("Estratégias: " + codEstrategias);
}
#After
public void tearDown() throws Exception {
}
#Test
public void test() {
}
}
public class Executar_Query_Bd_Multiplos_Resultados {
//Variáveis de BD
Connection conOracle = null;
Statement stmtOracle = null;
ResultSet rsetOracle = null;
public String Conectar(int Id_Estrategia1, int Id_Estrategia2) {
String retorno = "#;-1;#";
Boolean lb_continuar = true;
//StringBuilder ls_comando = new StringBuilder();
String ls_comando = new String();
try {
System.out.println("Conectando ao banco de dados Oracle...");
String url = "";
try {
//conectando aos bancos de dados
Class.forName("oracle.jdbc.driver.OracleDriver");
url = "jdbc:oracle:thin:#10.5.12.116:1521:desenv01";
DriverManager.setLoginTimeout(10);
conOracle = (Connection) DriverManager.getConnection(url, "bkofficeadm", "bkofficeadmdesenv01");
} catch (SQLException e) {
System.out.println("falha SQL >> " + e.getMessage());
} catch (Exception e) {
//System.out.println("falha geral >> " + e.getMessage());
e.printStackTrace();
lb_continuar = false;
}
//String teste = "'BKO - Rep Conectividade'";
if (lb_continuar) {
System.err.println("Preparando comando...");
System.out.println("");
ls_comando = "SELECT DS_ESTRATEGIA, ID_ESTRATEGIA"+
" FROM TB_BKOFFICE_ESTRATEGIA"+
" WHERE ID_ESTRATEGIA IN (" + Id_Estrategia1 + ", " + Id_Estrategia2 + ")";
System.out.println(ls_comando);
stmtOracle = conOracle.createStatement();
stmtOracle.setQueryTimeout(10);
rsetOracle = stmtOracle.executeQuery(ls_comando.replaceAll("\n", " ").trim());
if(rsetOracle.next()) {
retorno = rsetOracle.getString(1);
}
rsetOracle.close();
stmtOracle.close();
/*
Para comandos de Insert, Delete, ou Update
--------------------------------------------------------
stmtOracle = conOracle.createStatement();
stmtOracle.setQueryTimeout(10);
stmtOracle.execute(variavel_comando.toString());
conOracle.commit();
stmtOracle.close();
*/
}
} catch (Exception ex) {
System.out.println("Erro - " + ex.getMessage());
} finally {
try {
if (rsetOracle != null) {
rsetOracle.close();
}
} catch (Exception e) {
System.out.println("Erro ao fechar rset - " + e.getMessage());
}
try {
if (stmtOracle != null) {
stmtOracle.close();
}
} catch (Exception e) {
System.out.println("Erro ao fechar stmt - " + e.getMessage());
}
try {
if (conOracle != null && !conOracle.isClosed()) {
conOracle.close();
}
if (conOracle != null && !conOracle.isClosed()) {
conOracle.close();
}
} catch (Exception e) {
System.out.println("Erro ao fechar con - " + e.getMessage());
}
}
return retorno;
}
}
Output from SQL Devleoper query:
Output from Eclipse console:
You're doing this
if(rsetOracle.next()) {
retorno = rsetOracle.getString(1);
}
This runs once
Consider while instead:
List<String> retornos = new ArrayList<>();
while(rsetOracle.next()) {
retornos.add(rsetOracle.getString(1));
}
This will run until you're out of rows.
If something like this happens in the future, you'll want to modify your query to select count(*) ... and verify you get the same result in both the database workbench and your javacode. Then you'll at least know you've got the right query, and it's your presentation that's failing.
Note:
I understand this question is indeed a duplicate of other questions. However, those are difficult to search. I would propose this be a canonical answer.

Autoincrement error in jpa

This message gives me when it makes the insert in the database and does not give any error only gives this warning message.
Advertencia: The class RepeatableWriteUnitOfWork is already flushing. The query will be executed without further changes being written to the database. If the query is conditional upon changed data the changes may not be reflected in the results. Users should issue a flush() call upon completion of the dependent changes and prior to this flush() to ensure correct results.
NclDocumento documento = null;
try {
NclTipoDocumento tipo = findTipoDocumentoById(tipoD.getValue());
if (numero != null && numero != 0 && anioSelected != null) {
documento = findAcuerdoByNumeroAndAnioAndTipoDocumento(numero, anioSelected, tipo);
if (documento != null) {
return new Response<>(documento, ResponseStatus.OK_INSERT);
}
}
if (documento == null) {
documento = new NclDocumento();
documento.setNumero(122);
documento.setAnio(2014);
documento.setFechaEmision(new Date());
documento.setIdTipoDocumento(em.find(NclTipoDocumento.class,1));
if (firma != null && firma.getEmpleado() != null) {
documento.setIdFirma(firma.getEmpleado());
}
documento.setFechaCreacion(new Date());
documento.setUsuarioCreacion(usuarioLogueado);
documento.setActivo(true);
}
em.persist(documento);
em.flush();
return new Response<>(documento, ResponseStatus.OK_INSERT);
} catch (ConstraintViolationException ex) {
String validationError = getConstraintViolationExceptionAsString(ex);
log.error(validationError);
context.setRollbackOnly();
return new Response<>(ResponseStatus.ERROR_PARAMS, "Sucedio un error con la información: " + validationError);
} catch (Exception ex) {
processException(ex);
context.setRollbackOnly();
return new Response<>(ResponseStatus.ERROR, "Sucedio un error: " + ex.getMessage());
}

jaxb and jsr303

I am constructing object out of configuration using jaxb.
Until now I wrote custom function for validation but I would like to move into annotations.
e.g.:
#XmlElement
public void setNumber(Integer i){
if (i<10 || i>20) throw new IllegalArgumentException(...);
this.number=i;
}
The exceptions from this above approach were descriptive and gave me the position of the error in the xml.
I want to move into this:
#XmlElement
#Min(10)
#Max(20)
public void setNumber(Integer i){
this.number=i;
}
I can verify this by reading annotations in afterMarshal and running validation functions according to property annotations, but then I lose the actual place (in the xml) where the error occurred.
Do you have any though, should I use a different approach/framework for this problem?
EDIT: just to clarify, I must use annotation approach because I need the properties constraints metadata for the configuration editor I am writing
Here is a XJC plugin that I have used to solve this problem myself (in my case I needed annotations to do validation independant of XML schema, as I also have JMS endpoints):
What it does:
-It generates #valid annotation for objects that are not in the xs default schema (so annotations are cascaded)
-It generates #NotNull annotation for objects that has a MinOccur value >= 1 or for attributes with required use
-It generates #Size for lists that have minOccurs > 1
-It generates #Size if there is a maxLength or minLength restriction
-#DecimalMax for maxInclusive restriction
-#DecimalMin for minInclusive restriction
-#Digits if there is a totalDigits or fractionDigits restriction.
-#Pattern if there is a Pattern restriction
Please note that minExclusive and maxExclusive restrictions are excluded.
To use it, you have to package the class file along a META-INF/services/com.sun.tools.xjc.Plugin file with the content "com.sun.tools.xjc.addon.jaxb.JaxbValidationsPlugins" (that is, the fully qualified name of the class) and call XJC with the -XValidate switch.
It's not really difficult to implement, but I hope it will be useful for someone. The source code is attached as a TXT file. Enjoy!
package com.sun.tools.xjc.addon.jaxb;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.xml.sax.ErrorHandler;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JFieldVar;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.Plugin;
import com.sun.tools.xjc.model.CAttributePropertyInfo;
import com.sun.tools.xjc.model.CElementPropertyInfo;
import com.sun.tools.xjc.model.CPropertyInfo;
import com.sun.tools.xjc.outline.ClassOutline;
import com.sun.tools.xjc.outline.FieldOutline;
import com.sun.tools.xjc.outline.Outline;
import com.sun.xml.xsom.XSComponent;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.impl.AttributeUseImpl;
import com.sun.xml.xsom.impl.ElementDecl;
import com.sun.xml.xsom.impl.ParticleImpl;
public class JaxbValidationsPlugins extends Plugin {
public String getOptionName() {
return "Xvalidate";
}
public List<String> getCustomizationURIs() {
return Collections.singletonList(namespace);
}
private String namespace = "http://jaxb.dev.java.net/plugin/code-injector";
public boolean isCustomizationTagName(String nsUri, String localName) {
return nsUri.equals(namespace) && localName.equals("code");
}
public String getUsage() {
return " -Xvalidate : inject Bean validation annotations (JSR 303)";
}
public boolean run(Outline model, Options opt, ErrorHandler errorHandler) {
try {
for (ClassOutline co : model.getClasses()) {
for (CPropertyInfo property : co.target.getProperties()) {
if (property instanceof CElementPropertyInfo) {
recorrePropiedad((CElementPropertyInfo) property, co, model);
} else if (property instanceof CAttributePropertyInfo) {
recorrePropiedad((CAttributePropertyInfo) property, co, model);
}
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
static int i = 0;
/**
* XS:Element
*
* #param property
* #param clase
* #param model
*/
public void recorrePropiedad(CElementPropertyInfo property, ClassOutline clase, Outline model) {
FieldOutline field = model.getField(property);
XSComponent definicion = property.getSchemaComponent();
ParticleImpl particle = (ParticleImpl) definicion;
int maxOccurs = ((BigInteger) getField("maxOccurs", particle)).intValue();
int minOccurs = ((BigInteger) getField("minOccurs", particle)).intValue();
JFieldVar var = (JFieldVar) clase.implClass.fields().get(getField("privateName", property));
if (minOccurs < 0 || minOccurs >= 1) {
if (!hasAnnotation(var, NotNull.class)) {
System.out.println("#NotNull: " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(NotNull.class);
}
}
if(maxOccurs>1){
if (!hasAnnotation(var, Size.class)) {
System.out.println("#Size ("+minOccurs+","+maxOccurs+") " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(Size.class).param("min", minOccurs).param("max", maxOccurs);
}
}
ElementDecl declaracion = (ElementDecl) getField("term", particle);
if (declaracion.getType().getTargetNamespace().startsWith("http://hotelbeds.com")) {
if (!hasAnnotation(var, Valid.class)) {
System.out.println("#Valid: " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(Valid.class);
}
}
if (declaracion.getType() instanceof XSSimpleType) {
procesaType((XSSimpleType) declaracion.getType(), var, property.getName(), clase.implClass.name());
} else if (declaracion.getType().getBaseType() instanceof XSSimpleType) {
procesaType((XSSimpleType) declaracion.getType().getBaseType(), var, property.getName(), clase.implClass.name());
}
// if(declaracion.getType() instanceof
// if(declaracion.getType().ge)
// procesaType(declaracion.getType().getBaseType(),var);
}
/**
* XS:Attribute
*
* #param property
* #param clase
* #param model
*/
public void recorrePropiedad(CAttributePropertyInfo property, ClassOutline clase, Outline model) {
FieldOutline field = model.getField(property);
System.out.println("Tratando attributo " + property.getName() + " de la clase " + clase.implClass.name());
XSComponent definicion = property.getSchemaComponent();
AttributeUseImpl particle = (AttributeUseImpl) definicion;
JFieldVar var = (JFieldVar) clase.implClass.fields().get(getField("privateName", property));
if (particle.isRequired()) {
if (!hasAnnotation(var, NotNull.class)) {
System.out.println("#NotNull: " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(NotNull.class);
}
}
if (particle.getDecl().getType().getTargetNamespace().startsWith("http://hotelbeds.com")) {
if (!hasAnnotation(var, Valid.class)) {
System.out.println("#Valid: " + property.getName() + " de la clase " + clase.implClass.name());
var.annotate(Valid.class);
}
}
procesaType(particle.getDecl().getType(), var, property.getName(), clase.implClass.name());
}
public void procesaType(XSSimpleType tipo, JFieldVar field, String campo, String clase) {
if (tipo.getFacet("maxLength") != null || tipo.getFacet("minLength") != null) {
Integer maxLength = tipo.getFacet("maxLength") == null ? null : parseInt(tipo.getFacet("maxLength").getValue().value);
Integer minLength = tipo.getFacet("minLength") == null ? null : parseInt(tipo.getFacet("minLength").getValue().value);
if (!hasAnnotation(field, Size.class)) {
System.out.println("#Size(" + minLength + "," + maxLength + "): " + campo + " de la clase " + clase);
field.annotate(Size.class).param("min", minLength).param("max", maxLength);
}
}
/*
* <bindings multiple="true" node=
* "//xs:complexType/.//xs:element[contains(#type,'IntPercentRestriction')]"
* > <annox:annotate> <annox:annotate
* annox:class="javax.validation.constraints.Digits" integer="3"
* fraction="2" /> <annox:annotate
* annox:class="javax.validation.constraints.Min" value="-100" />
* value="100" /> </annox:annotate> </bindings>
*//*
* <xs:restriction base="xs:decimal"> <xs:fractionDigits value="2"/>
* <xs:maxInclusive value="100.00"/> <xs:minInclusive
* value="-100.00"/> <xs:totalDigits value="5"/> </xs:restriction>
*/
if (tipo.getFacet("maxInclusive") != null && tipo.getFacet("maxInclusive").getValue().value != null && !hasAnnotation(field,DecimalMax.class)){
System.out.println("#DecimalMax(" + tipo.getFacet("maxInclusive").getValue().value + "): " + campo + " de la clase " + clase);
field.annotate(DecimalMax.class).param("value", tipo.getFacet("maxInclusive").getValue().value);
}
if (tipo.getFacet("minInclusive") != null && tipo.getFacet("minInclusive").getValue().value != null && !hasAnnotation(field,DecimalMin.class)){
System.out.println("#DecimalMin(" + tipo.getFacet("minInclusive").getValue().value + "): " + campo + " de la clase " + clase);
field.annotate(DecimalMin.class).param("value", tipo.getFacet("minInclusive").getValue().value);
}
if (tipo.getFacet("totalDigits") != null) {
Integer totalDigits = tipo.getFacet("totalDigits") == null ? null : parseInt(tipo.getFacet("totalDigits").getValue().value);
int fractionDigits = tipo.getFacet("fractionDigits") == null ? 0 : parseInt(tipo.getFacet("fractionDigits").getValue().value);
if (!hasAnnotation(field, Digits.class)) {
System.out.println("#Digits(" + totalDigits + "," + fractionDigits + "): " + campo + " de la clase " + clase);
JAnnotationUse annox = field.annotate(Digits.class).param("integer", (totalDigits - fractionDigits));
if (tipo.getFacet("fractionDigits") != null) {
annox.param("fraction", fractionDigits);
}
}
}
/**
* <annox:annotate annox:class="javax.validation.constraints.Pattern"
message="Name can only contain capital letters, numbers and the simbols '-', '_', '/', ' '"
regexp="^[A-Z0-9_\s//-]*" />
*/
if(tipo.getFacet("pattern")!=null){
System.out.println("#Pattern(" +tipo.getFacet("pattern").getValue().value+ "): " + campo + " de la clase " + clase);
if (!hasAnnotation(field, Pattern.class)) {
field.annotate(Pattern.class).param("regexp", tipo.getFacet("pattern").getValue().value);
}
}
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public boolean hasAnnotation(JFieldVar var, Class anotacion) {
List<JAnnotationUse> lista = (List<JAnnotationUse>) getField("annotations", var);
if (lista != null) {
for (JAnnotationUse uso : lista) {
if (((Class) getField("clazz._class", uso)).getCanonicalName().equals(anotacion.getCanonicalName())) {
return true;
}
}
}
return false;
}
private Integer parseInt(String valor) {
try {
Integer i = Integer.parseInt(valor);
if (i < 2147483647 && i > -2147483648) {
return i;
}
} catch (Exception e) {
try{
return (int)Math.round(Double.parseDouble(valor));
}catch(Exception ex){
;
}
}
return null;
}
/*
private Long parseLong(String valor) {
try {
Long i = Long.parseLong(valor);
if (i < 2147483647 && i > -2147483648) {
return i;
}
} catch (Exception e) {
return Math.round(Double.parseDouble(valor));
}
return null;
}
*/
private Object getField(String path, Object oo) {
try {
if (path.contains(".")) {
String field = path.substring(0, path.indexOf("."));
Field campo = oo.getClass().getDeclaredField(field);
campo.setAccessible(true);
Object result = campo.get(oo);
return getField(path.substring(path.indexOf(".") + 1), result);
} else {
Field campo = getSimpleField(path, oo.getClass());
campo.setAccessible(true);
return campo.get(oo);
}
} catch (Exception e) {
System.out.println("Field " + path + " not found on " + oo.getClass().getName());
}
return null;
}
private static Field getSimpleField(String fieldName, Class<?> clazz) {
Class<?> tmpClass = clazz;
try {
do {
for (Field field : tmpClass.getDeclaredFields()) {
String candidateName = field.getName();
if (!candidateName.equals(fieldName)) {
continue;
}
field.setAccessible(true);
return field;
}
tmpClass = tmpClass.getSuperclass();
} while (clazz != null);
} catch (Exception e) {
System.out.println("Field '" + fieldName + "' not found on class " + clazz);
}
return null;
}
}
You should look at https://github.com/krasa/krasa-jaxb-tools
which is improved and mavenized version of Vicente's code.
This depends on how are you reading the file and how do you plan to show errors. Using IAE is better if you also plan to construct the class programatically. Using JSR-303 is better when you also use it with JavaEE 6. Also, you must think if your user needs to know the error line number.
And remember: the first (pure-POJO) way ensures that no object will ever be inconsistent (marshalling or unmarshalling), while JSR-303 requires someone to call the validation functions (as well as requiring the framework classes in classpath).

hibernate interceptors : afterTransactionCompletion

I wrote a Hibernate interceptor :
public class MyInterceptor extends EmptyInterceptor {
private boolean isCanal=false;
public boolean onSave(Object entity, Serializable arg1, Object[] arg2, String[] arg3, Type[] arg4) throws CallbackException {
for(int i=0;i<100;i++){
System.out.println("Inside MyInterceptor(onSave) : "+entity.toString());
}
if(entity instanceof Canal){
isCanal=true;
}
return false;
}
public void afterTransactionCompletion(Transaction tx){
if(tx.wasCommitted()&&(isCanal)){
for(int i=0;i<100;i++){
System.out.println("Inside MyInterceptor(afterTransactionCompletion) : Canal was saved to DB.");
}
}
}
I can see the method onSave executing fine, but afterTransactionCompletion method never gets executed even though the transaction is successfully commited to the database.
I need a way to track every time a Canal object is successfully saved to the DB and react by printing some messages. is that feasible ? and how ?
Here is the method I use to save objects in the DB :
public static Object enregObjet(Object obj) throws UpdateException,
EnregException, ErreurException {
Transaction tx = null;
try {
Session s = InterfaceBD.currentSession();
tx = s.beginTransaction();
try {
// Positionner les champs dteUti et dteUtiModif
Method dteUtiSetter = null;
;
// Objet en insertion
dteUtiSetter = obj.getClass().getMethod("setDteUti",
new Class[] { java.util.Date.class });
dteUtiSetter.invoke(obj, new Object[] { new java.util.Date() });
} catch (NoSuchMethodException ex) {
;// Le champ dteUtiModif n'existe pas
}
// Enregistrer
IardNum.numeroterCode(obj);
IardNum.numeroterId(obj);
s.save(obj);
s.flush();
tx.commit();
try {
String id = "";
// Positionner les champs dteUti et dteUtiModif
Method idGetter = null;
// Objet en insertion
idGetter = obj.getClass().getMethod("getId");
id = (String) idGetter.invoke(obj);
Connection conn = InterfaceBD.getConn();
IardGenerator3.cleanSeq(id, conn);
conn.close();
} catch (NoSuchMethodException ex) {
;// Le champ dteUtiModif n'existe pas
}
catch(ClassCastException ex){
;//just ignore it because we are dealing with a PK class (e.g : CausesAnnexesSinistrePK).
}
s.clear();
return obj;
}
I would suggest using DAO design template. Basicaly you just create an class, which will save Canal object and use it everywhere where you need to save it.
In this class you can add all logic you need.

Categories