Archivo | 16:09 hrs.

Estandarizando los codigos internos de error

07 feb 2007

Sera deformacion profesional heredada de mi experiencia laboral anterior, pero cuando nos hemos decidido a crear un Java5 enum en nuestras librerias de desarrollo para la estandarizacion de los codigos de error, me he empeñado en reservar/usar los codigos de respuesta del estandard SIP (Session Initiation Protocol). Realmente son un superconjunto de los codigos de respuesta estandard del protocolo HTTP, con los que la mayoria estamos mas que familiarizados, aunque solo sea de navegar en busca del fin de internet (sic).

Basicamente mi idea ha sido reservar todos los codigos de error entre 100 y 699 para codigos compatibles con el estandard SIP:


1xx: Provisional — Respuestas provisionales, de caracter informativo. Se envia un 1xx si se espera que la respuesta final tarde mas de 200ms.
2xx: Success — Para los casos en que todo ha ido bien.
3xx: Redirection — Hacen falta acciones adicionales para completar correctamente la petición.
4xx: Client Error — Errores en capa cliente, o peticiones mal formadas.
5xx: Server Error — Fallos en servidor ante una peticion aparentemente correcta.
6xx: Global Failure — Fallo global.

Obviamente, para un enum que contenga codigos de error, las respuestas informativas o de exito no nos interesan, pero en cualquier caso decidimos reservar esos rangos y no usarlos. Simple cuestion de compatibilidad hacia delante.

Estos codigos no son ningun secreto y estan disponibles en cientos de paginas en internet, pero picarselos en un enum resulta bastante co~azo, la verdad… asi que aqui estan por si alguien quiere reutilizar…


public enum CodigoError{
	//Especial
	/* Copyrighted */
	//0xx - General (Viavansi)
	/* Copyrighted */
	//1xx - Provisional (Standard) - Informativo de progreso - No usar como codigo de error!
	//2xx - Success (Standard) - No usar como codigo de error!
	//3xx - Redirection (Standard)
	SIP_MULTIPLE_CHOICES(300,"Multiple Choices."),//SIP
	SIP_MOVED_PERMANENTLY(301,"Moved Permanently."),//SIP
	SIP_MOVED_TEMPORARILY(302,"Moved Temporarily."),//SIP
	SIP_USE_PROXY(305,"Use Proxy."),//SIP
	SIP_ALTERNATIVE_SERVICE(380,"Alternative Service."),//SIP
	//4xx - Client or Request (Standard)
	SIP_BAD_REQUEST(400,"Bad Request."),//SIP
	SIP_UNAUTHORIZED(401,"Unauthorized. Need to register."),//SIP Proxys should use proxy authorization 407
	SIP_PAYMENT_REQUIRED(402,"Payment Required"),//SIP
	SIP_FORBIDDEN(403,"Forbidden."),//SIP
	SIP_NOT_FOUND(404,"Not Found."),//SIP
	SIP_METHOD_NOT_ALLOWED(405,"Method Not Allowed."),//SIP
	SIP_REQ_NOT_ACCEPTABLE(406,"Not Acceptable."),//SIP
	SIP_PROXY_AUTH_REQ(407,"Proxy Authentication Required."),//SIP
	SIP_REQUEST_TIME_OUT(408,"Request Timeout."),//SIP
	SIP_GONE(410,"Gone: The user existed once, but is not available here any more."),//SIP
	SIP_ENTITY_TOO_LARGE(413,"Request Entity Too Large."),//SIP
	SIP_URI_TOO_LONG(414,"Request-URI Too Long."),//SIP
	SIP_UNSOPPORTED_MEDIA(415,"Unsupported Media Type."),//SIP
	SIP_UNSOPPORTED_URI_SCHEME(416,"Unsupported URI Scheme."),//SIP
	SIP_BAD_EXTENSION(420,"Bad Extension."),//SIP
	SIP_EXTENSION_REQUIRED(421,"Extension Required."),//SIP
	SIP_INTERVAL_TOO_SHORT(423,"Interval Too Brief."),//SIP
	SIP_TEMPORARILY_UNAVAILABLE(480,"Temporarily Unavailable."),//SIP
	SIP_TRANSACTION_NOT_EXISTS(481,"Transaction Does Not Exist."),//SIP
	SIP_LOOP(482,"Loop Detected."),//SIP
	SIP_TOO_MANY_HOPS(483,"Too Many Hops."),//SIP
	SIP_WRONG_ADDRESS(484,"Address Incomplete."),//SIP
	SIP_AMBIGUOUS(485,"Ambiguous."),//SIP
	SIP_BUSY(486,"Busy Here."),//SIP
	SIP_REQUEST_TERMINATED(487,"Request Terminated."),//SIP
	SIP_REQ_NOT_ACCEPTABLE_HERE(488,"Not Acceptable Here."),//SIP
	SIP_REQ_PENDING(491,"Request Pending."),//SIP
	SIP_UNDECIPHERABLE(493,"Undecipherable: Could not decrypt."),//SIP
	//5xx - Server (Standard)
	SIP_SERVER_ERROR(500,"Server Internal Error."),//SIP
	SIP_NOT_IMPLEMENTED_HERE(501,"Not Implemented: The request method is not implemented here"),//SIP
	SIP_BAD_GATEWAY(502,"Bad Gateway."),//SIP
	SIP_SERVICE_UNAVAILABLE(503,"Service Unavailable."),//SIP
	SIP_SERVER_TIME_OUT(504,"Server Time-out."),//SIP
	SIP_VERSION_NOT_SUPPORTED(505,"Version Not Supported:The server does not support this version"),//SIP
	SIP_MESSAGE_TOO_LARGE(513,"Message Too Large."),//SIP
	//6xx - Global (Standard)
	SIP_BUSY_EVERYWHERE(600,"Busy Everywhere."),//SIP
	SIP_DECLINE(603,"Decline."),//SIP
	SIP_NOT_EXISTS(604,"Does Not Exist Anywhere."),//SIP
	SIP_NOT_ACCEPTABLE(606,"Not Acceptable."),//SIP
	//10xx - Base de Datos (Viavansi)
	/* Copyrighted */
	//11xx - XML (Viavansi)
	/* Copyrighted */;

	private final int codigo;
    private final String mensaje;

    CodigoError(int cod, String mensaje) {
        this.codigo = cod;
        this.mensaje = mensaje;
    }

    /**
	 * @return Devuelve el mensaje por defecto.
	 */
	public String getMensaje() {
		return mensaje;
	}

	/**
	 * @return Devuelve el codigo de error asociado.
	 */
	public int getCodigo() {
		return codigo;
	}

    /* (non-Javadoc)
     * @see java.lang.Enum#toString()
     */
    @Override
    public String toString() {
    	return mensaje+"[codigo error:"+codigo+"]";
    }

}

Cuando Hibernate ataca a Postgres…

07 feb 2007

Quizas este post te ayude si estas buscando una solucion para alguna de las siguientes cuestiones:

  • Pasarle comillas a la BBDD atraves de Hibernate
  • Usar palabras reservadas del gestor de BBDD como nombre de columna o tabla en JPA.
  • Tienes una org.postgresql.util.PSQLException
  • Tienes una excepcion: column notation applied to type name, which is not a composite type

Recientemente jugando con JPA contra Postgres nos hemos encontrado con un problema de los que le pueden volver loco a uno. La excepcion que teniamos era:



 org.postgresql.util.PSQLException: ERROR: .user_id column notation applied to type name, which is not a composite type

Es el tipo de mensaje de error que despista y te puede hacer dar vueltas durante horas (o dias) buscando el problema donde no es.
Nosotros estabamos convencidos de que habia algo erroneo en nuestras annotations de las columnas

@Column(name="user_id")

Pero lo que ya nos hacia tirarnos de los pelos era que nos pasaba lo mismo ya hiciesemos la query consultando user_id o email.



 org.postgresql.util.PSQLException: ERROR: .email column notation applied to type name, which is not a composite type

En general nos ocurria con cualesquiera columnas de nuestra tabla user.

Al final dimos con lo que estaba ocurriendo… el problema estaba en la annotation

@Table(name="user")

Os vais a reir… Resulta que user es una palabra reservada de Postgres, como tambien lo es id y algunas otras. Asi que si llamamos user a nuestra tabla, en la annotation necesitamos usar comillas para que el motor de BBDD no se haga un lio.

Y la forma de pasarle a Hibernate las comillas viene explicada aqui:
http://www.hibernate.org/hib_docs/reference/en/html/mapping.html#mapping-quotedidentifiers

O sea, que usando la tilde invertida -`- Hibernate nos la traduce a las comillas adecuadas del dialecto adecuado.

Basicamente, nuestro problema se arreglo haciendo:

@Table(name="`user`")

Apagando VIAVANSI

01 feb 2007

En VIAVANSI nos hemos sumado al apagón… pero el Administrador de Sistemas no nos ha dejado apagar el servidor!! :-(