None of mybatis typehandler getResult is entered - mybatis

I think I'm seeking for trouble for myself using complex structure but I need to get over this problem.
I have object nested in object, then the object list
Here's the base Entity
#Data
public class BaseEntity {
private Long id;
private String name;
private String description;
}
Here's my impactEntity built on the top of base Entity
#Data
public class ImpactEntity implements Structable{
private String ref;
private String ASOF;
private Long deliverTime;
private String SLAMissed;
private BaseEntity client;
private BaseEntity application;
private BaseEntity deliverable;
}
Here's my real final object:
#Data
public class IncidentEntity {
private String PID;
private String ID;
private String NID;
private String REF;
private String RREF;
private String ASOF;
private Long StartTime;
private Long endTime;
private String description;
private String active;
private Long createAt;
private List<ImpactEntity> impacts;
}
Here's my incidentMapper:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.well.valley.mapper.IncidentMapper" >
<resultMap id="IncidentEntity" type="org.well.valley.entity.IncidentEntity">
<result column="PID" jdbcType="VARCHAR" property="PID" />
<result column="ID" jdbcType="VARCHAR" property="ID" />
<result column="NID" jdbcType="VARCHAR" property="NID" />
<result column="REF" jdbcType="VARCHAR" property="REF" />
<result column="RREF" jdbcType="VARCHAR" property="RREF" />
<result column="ASOF" jdbcType="VARCHAR" property="ASOF" />
<result column="STARTTIME" jdbcType="INTEGER" property="startTime" />
<result column="ENDTIME" jdbcType="INTEGER" property="endTime" />
<result column="DESCRIPTION" jdbcType="VARCHAR" property="description" />
<result column="ACTIVE" jdbcType="VARCHAR" property="active" />
<result column="CREATEAt" jdbcType="INTEGER" property="createAt" />
<result property="impacts" column="IMPACTS" typeHandler="org.well.valley.utils.typehandlers.OracleTypeHandler" />
</resultMap>
<select id="get" statementType="CALLABLE" parameterType="org.well.valley.entity.IncidentEntity">
call get_incidents(
#{ASOF, jdbcType=VARCHAR},
#{ref, jdbcType=VARCHAR},
#{active, jdbcType=VARCHAR},
#{outParam.c1, mode=OUT, jdbcType=CURSOR, javaType=java.sql.ResultSet, resultMap=IncidentEntity}
)
</select>
</mapper>
I'm using a customized typeHandler to deal with
<result property="impacts" column="IMPACTS" typeHandler="org.well.valley.utils.typehandlers.OracleTypeHandler" />
Here's my full body of the OracleTypeHandler. I want to make it very generic and be able to deal with anything, including something like List although I haven't started the code to deal with the List in the resultset yet.
public class OracleTypeHandler<T> extends BaseTypeHandler<T> {
private Logger logger = LoggerFactory.getLogger(getClass());
private ObjectMapper objectMapper = new ObjectMapper();
private DBMapperBean getDBMapperBean() {
return SpringContext.getBean(DBMapperBean.class);
}
private Class<T> type;
protected int getIndex(ResultSetMetaData data, String columnName) throws SQLException {
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>11111111111111111111111111");
for (int i = 1; i <= data.getColumnCount(); i++) {
String c = data.getColumnName(i);
if(columnName.equals(c))
{
return i;
}
}
return -1;
}
public OracleTypeHandler(Class<T> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
logger.info(">>>>>>>>>>>>>>>>>>>>Type is:{}", type);
}
#Override
public void setNonNullParameter(PreparedStatement ps, int index, T parameter, JdbcType jdbcType)
throws SQLException {
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>333333333333333333333333");
Connection conn = ps.getConnection();
if(parameter.getClass().isArray()) {
if(parameter instanceof String[]) {
Array array = ((OracleConnection) conn).createOracleArray("STRINGARRAY", parameter);
ps.setArray(index, array);
array.free();
}
}
}
#Override
public T getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
ResultSetMetaData metaData = resultSet.getMetaData();
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>444444444444444444444444444444");
int index = getIndex(metaData, columnName);
String columnClassName = metaData.getColumnClassName(index);
if(columnClassName.equals("oracle.jdbc.OracleStruct"))
{
java.sql.Struct o = (java.sql.Struct)resultSet.getObject(index);
return extractObject(o);
}else if(columnClassName.equals("oracle.jdbc.OracleArray"))
{
Array array = resultSet.getArray(columnName);
Object r = array.getArray();
array.free();
return (T) r;
}
return null;
}
private String typeNameConvert(String type, String target)
{
if(target.equals("DBTYPE"))
{
return type.concat("TYPE");
}else
{
return type.substring(0, type.length()-4);
}
}
private T extractObject(Struct o) throws SQLException {
String typeName = o.getSQLTypeName();
typeName = typeName.substring(typeName.lastIndexOf(".")+1);DBMapperBean dbMapperBean = getDBMapperBean();
typeName = typeNameConvert(typeName, "JAVATYPE");
if(typeName.endsWith("ARRAY"))
{
switch (typeName){
case "STRINGARRAY":
break;
}
}else {
HashMap <String, Class> map = dbMapperBean.getMap();
try {
Class<?> cls = (Class<?>) map.get(typeName);
Structable obj = (Structable) cls.getDeclaredConstructor().newInstance();
Object[] attrs = o.getAttributes();
List<Field> fields = obj.getOrderedField(obj.getClass().getDeclaredFields());
int i = 0;
for (Field f : fields) {
f.setAccessible(true);
Object source = attrs[i];
if(source == null)
{
f.set(obj, null);
}
else {
Class targetType = f.getType();
Class sourceType = source.getClass();
if (Number.class.isAssignableFrom(targetType) && Number.class.isAssignableFrom(sourceType)) {
if (targetType == Long.class) {
source = Long.parseLong(source.toString());
}
}
try {
f.set(obj, source);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
i++;
}
return (T) obj;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return null;
}
#Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>66666666666666666");
Struct struct =(java.sql.Struct) rs.getObject(columnIndex);
return extractObject(struct);
}
#Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>7777777777777777777");
Struct struct =(java.sql.Struct) cs.getObject(columnIndex);
return extractObject(struct);
}
}
So even before the DB stored procedure is called, the constructor of the OracleTypeHandler is called, which is expected, as it's to build up a List of the object of objects
19:58:28.439 INFO o.w.v.u.t.OracleTypeHandler - >>>>>>>>>>>>>>>>>>>>Type is:class org.well.valley.entity.BaseEntity
19:58:33.692 INFO o.w.v.u.t.OracleTypeHandler - >>>>>>>>>>>>>>>>>>>>Type is:class org.well.valley.entity.BaseEntity
20:02:43.477 INFO o.w.v.u.t.OracleTypeHandler - >>>>>>>>>>>>>>>>>>>>Type is:class org.well.valley.entity.BaseEntity
20:02:47.161 INFO o.w.v.u.t.OracleTypeHandler - >>>>>>>>>>>>>>>>>>>>Type is:class org.well.valley.entity.BaseEntity
20:03:00.370 INFO o.w.v.u.t.OracleTypeHandler - >>>>>>>>>>>>>>>>>>>>Type is:class [Ljava.lang.String;
20:03:16.080 INFO o.w.v.u.t.OracleTypeHandler - >>>>>>>>>>>>>>>>>>>>Type is:interface java.util.List
However, after my DB stored procedure is called, none of the 3 getNullableResult methods in the typehandler is entered, while I would expect for whatever result set is retrieved one of them should be entered. To be more specific I think this one should be entered, as this is the one to retrieve the result using column name. I was expecting to do some job inside this method. However, it's not entered, and returned an empty List(but if I call the procedure in DB directly I got the result)
public T getNullableResult(ResultSet resultSet, String columnName) throws SQLException
So - can someone please advise what's the reason the getNullableResult methods were not entered? Which typehandler Mybatis us in this case to deal with my impactList?
Thanks a million

Related

mybatis custom type handler without annoations

I'm new to mybatis. I am trying to map a JDBC integer to a custom class. All the examples that I have seen on this have used annotations, is it possible to not use annotations and do this? Any example would be greatly appreciated.
Sreekanth
It is definitely possible and is described in general in Configuration and in Mapper sections of the documentation.
Define the handler first:
#MappedJdbcTypes(JdbcType.INTEGER)
public class MyClassHandler extends BaseTypeHandler<MyClass> {
#Override
public void setNonNullParameter(PreparedStatement ps, int i,
MyClass parameter, JdbcType jdbcType) throws SQLException {
ps.setInt(i, parameter.asInt());
}
#Override
public MyClass getNullableResult(ResultSet rs, String columnName)
throws SQLException {
int val = rs.getInt(columnName);
if (rs.wasNull())
return null;
else
return MyClass.valueOf(val);
}
#Override
public MyClass getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
int val = rs.getInt(columnIndex);
if (rs.wasNull())
return null;
else
return MyClass.valueOf(val);
}
#Override
public MyClass getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
int val = cs.getInt(columnIndex);
if (cs.wasNull())
return null;
else
return MyClass.valueOf(val);
}
}
Then configure it in mybatis-config.xml:
<typeHandlers>
<typeHandler handler="my.company.app.MyClassHandler"/>
</typeHandlers>
Now you can use it in xml mappers.
If you have a class
class SomeTypeEntity {
private MyClass myClassField;
};
For querying the field configure handler in the resultMap like this:
<resultMap id="someMap" type="SomeTypeEntity">
<result property="myClassField" column="my_class_column" typeHandler="my.company.app.MyClassHandler"/>
</resultMap>
For insert/update use it like this:
<update id="updateSomeTypeWithMyClassField">
update some_type
set
my_class_column = #{someTypeEntity.myClassField, typeHandler=my.company.app.MyClassHandler},
</update>
for mapper method:
void updateSomeTypeWithMyClassField(#Param("someTypeEntity") SomeTypeEntity entity);

My action cant get data from a struts2 select tag

I'm developing a web app using struts 2 framework and i'm facing a problem with select tag in a jsp.
The select tag seems to work fine, but as soon as i press the submit button, my action cannot get the data from the select.
I have looked for problems about select, but all of them seem to be related with the list.
In my case, the list is shown fine. So, I'm quite lost and I dont know what should I do.
Here are my jsp code and my action code. When I press the submit, it suppose that the form will be sent to my action, and I shoud get the data from the form, but when I print the data is always null.
JSP Code:
<s:form action="borrarCita" method="post">
<s:select id="idCita" name="idCita" list="pendings" listKey="idCita" listValue="fecha" label="Elija una cita a anular"></s:select>
<s:submit value="Aceptar"/>
</s:form>
The action code:
public class CitasAction extends ActionSupport implements SessionAware{
private static final long serialVersionUID = 1L;
private Map session = ActionContext.getContext().getSession();
private List pendings= new ArrayList<Cita>();
private String idCita;
private String desplegarCitasPendientes;
private String pedirCita;
private String consultarCitas;
private String citaAnulada;
public String execute(){
return SUCCESS;
}
public String pedirCita(){
setCitaAnulada("");
setDesplegarCitasPendientes("");
setConsultarCitas("");
DbService db = (DbService)session.get("db");
Paciente paciente = (Paciente)session.get("Paciente");
List listaMedicos = db.getListaMedicos();
session.remove("listaCitas");
session.put("listaMedicos", listaMedicos);
setPedirCita("ok");
return SUCCESS;
}
public String desplegarCitasPendientes(){
setCitaAnulada("");
setPedirCita("");
setConsultarCitas("");
Paciente pac = (Paciente)session.get("user");
Iterator<Cita> nombreIterator = pac.getCitas().iterator();
while(nombreIterator.hasNext()){
Cita primera = nombreIterator.next();
if(primera.getStatus().equals("Pending")){
getPendings().add(primera);
}
}
setDesplegarCitasPendientes("ok");
return SUCCESS;
}
public String borrarCita(){
setConsultarCitas("");
setPedirCita("");
setDesplegarCitasPendientes("");
System.out.println(getIdCita());
System.out.println(ActionContext.getContext().getParameters().toString());
Paciente pac = (Paciente)session.get("user");
/*
Iterator<Cita> iterator = pac.getCitas().iterator();
while(iterator.hasNext()){
Cita primera = iterator.next();
if(primera.getFecha().equals(getFecha())){
iterator.remove();
break;
}
}
pac.setCitas(getPendings());
pac.getCitas().remove(getCitaSeleccionada());
session.put("user", pac);
DbService db = (DbService)session.get("db");
db.uploadPaciente(pac);*/
setCitaAnulada("ok");
return SUCCESS;
}
public String consultarCitas(){
setPedirCita("");
setDesplegarCitasPendientes("");
setCitaAnulada("");
setConsultarCitas("ok");
return SUCCESS;
}
public Map getSession() {
return session;
}
public void setSession(Map session) {
this.session = session;
}
public List getPendings() {
return pendings;
}
public void setPendings(List pendings) {
this.pendings = pendings;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public String getDesplegarCitasPendientes() {
return desplegarCitasPendientes;
}
public void setDesplegarCitasPendientes(String desplegarCitasPendientes) {
this.desplegarCitasPendientes = desplegarCitasPendientes;
}
public String getPedirCita() {
return pedirCita;
}
public void setPedirCita(String pedirCita) {
this.pedirCita = pedirCita;
}
public String getConsultarCitas() {
return consultarCitas;
}
public void setConsultarCitas(String consultarCitas) {
this.consultarCitas = consultarCitas;
}
public String getCitaAnulada() {
return citaAnulada;
}
public void setCitaAnulada(String citaAnulada) {
this.citaAnulada = citaAnulada;
}
public String getIdCita() {
return idCita;
}
public void setIdCita(String idCita) {
this.idCita = idCita;
}
}
So, to sum up, I have that select tag in a jsp and when a press the submit, the action doesn't get any data from the select.
I hope someone can help me with this because it's driving me crazy.
If you need more information, please let me know and I will try to post it as soon as posible.
Thanks in advance.
Edit:
Here is a part of the Cita.class code. Also it has the setters and the getters for every attribute.
public class Cita implements Serializable{
#Id #GeneratedValue
#Column(name="CITA_ID")
private int idCita;
#Column(name="FECHA")
#Temporal(TemporalType.DATE)
private Date fecha;
#Column(name="HORA")
#Temporal(TemporalType.TIME)
private Date hora;
#Column(name="ESTADO")
private String status;
#Column(name="ESPECIALIDAD")
private String especialidad;
#ManyToOne
#JoinColumn(name="MEDICO_ID")
private Medico medico;
#ManyToOne
#JoinColumn(name="PACIENTE_ID")
private Paciente paciente;
And here is the struts.xml:
<interceptors>
<interceptor name="logger" class="interceptor.LoginInterceptor"/>
<interceptor-stack name="myStack">
<interceptor-ref name="logger"/>
</interceptor-stack>
</interceptors>
<action name="desplegarCitasPendientes" class="action.CitasAction" method="desplegarCitasPendientes">
<interceptor-ref name="myStack"/>
<result name="success">/citas.jsp</result>
<result name="login" type="redirect">/index.jsp</result>
<result name="input">/index.jsp</result>
</action>
<action name="borrarCita" class="action.CitasAction" method="borrarCita">
<interceptor-ref name="myStack"/>
<result name="success">/citas.jsp</result>
<result name="login" type="redirect">/index.jsp</result>
<result name="input">/index.jsp</result>
</action>
#Jeroen, sorry for the huge wall of code. It was my first post here.
#Roman, I hope this helps you to help me :-)
Thanks for your replies guys.
Edit 2:
Here is my LoginInterceptor:
public class LoginInterceptor extends AbstractInterceptor {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public String intercept(final ActionInvocation invocation) throws Exception {
Map<String, Object> session = invocation.getInvocationContext().getSession();
// sb: if the user is already signed-in, then let the request through.
if (session.get("user") != null) {
return invocation.invoke();
}else{
System.out.println("redirect");
return "login";
}
}
}
If you need something else, let me know :-)
Looks like a Interceptor issue.
What is myStack ?
Here's a sample stack I use in my projects (with Login Interceptor)
<package name="test" extends="struts-default">
<interceptors>
<interceptor name="nlogin" class="interceptors.LoginInterceptor"/>
<interceptor-stack name="loginStack">
<interceptor-ref name="nlogin"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="loginStack"/>
<action name="test-list" class="actions.InboxAction">
<result>/pages/inbox/list.jsp</result>
</action>
</package>
loginStack is being used as the defaultStack for all actions in that package, because of <default-interceptor-ref name="loginStack"/>
ok guys, It seems that I fixed it. Thanks to the coding_idiot's answer, I was able to figure out what was wrong. It seems that lack of defaultStack in my own stack was the problem. I just added the defaultStack and it looks like working fine now.
So, thank you very much to everyone and specially to coding_idiot.
The code finally looks like:
<interceptors>
<interceptor name="logger" class="interceptor.LoginInterceptor"/>
<interceptor-stack name="myStack">
<interceptor-ref name="logger"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>

JSF forms strange behavior

I have no idea why my forms behave in such way.
This is my JSF page:
<h:body>
<h:form>
<h:form>
<h:selectOneMenu value="#{productBean.product}" converter="#{productConverter}" validator="com.jsf.ProductAvailableValidator">
<f:selectItems value="#{productBean.pizza}" var="pizza" itemValue="#{pizza}" itemLabel="#{pizza.name}" />
<h:commandButton value="Dodaj" action="#{productBean.addToOrder(productBean.product.name)}" /></h:selectOneMenu>
</h:form>
<h:form>
<h:selectOneMenu value="#{productBean.product}" converter="#{productConverter}" validator="com.jsf.ProductAvailableValidator">
<f:selectItems value="#{productBean.drink}" var="drink" itemValue="#{drink}" itemLabel="#{drink.name}" />
<h:commandButton value="Dodaj" action="#{productBean.addToOrder(productBean.product.name)}" /></h:selectOneMenu>
</h:form>
<h:form>
<h:selectOneMenu value="#{productBean.product}" converter="#{productConverter}" validator="com.jsf.ProductAvailableValidator">
<f:selectItems value="#{productBean.other}" var="other" itemValue="#{other}" itemLabel="#{other.name}" />
<h:commandButton value="Dodaj" action="#{productBean.addToOrder(productBean.product.name)}" /></h:selectOneMenu>
</h:form>
<messages />
<h:outputText value="#{productBean.order}" />
<h:commandButton value="Wyczyść" action="#{ProductBean.clearOrder()}" /></h:form>
</h:body>
And this is my ProductBean:
#ManagedBean
#SessionScoped
public class ProductBean extends Connector
{
private List<Product> products;
private List<Product> pizza;
private List<Product> drink;
private List<Product> other;
boolean first = true;
private StringBuilder order = new StringBuilder();
public String getOrder() {
return order.toString();
}
private Product product;
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public void addToOrder(String prod)
{
System.out.println("dodaje");
if(first)
{
first = false;
this.order.append(prod);
}
else
this.order.append(" + ").append(prod);
}
public void clearOrder()
{
this.order = null;
first = true;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public ProductBean() throws SQLException
{
resultSet = statement.executeQuery("SELECT * FROM dbo.products");
products = new ArrayList<Product>();
while(resultSet.next())
{
product = new Product();
product.setId_product(resultSet.getInt("id_product"));
product.setName(resultSet.getString("name"));
product.setCategory(resultSet.getInt("category_id"));
product.setIs_available(resultSet.getInt("is_available"));
products.add(product);
}
}
public Product getProductById(int id)
{
Iterator<Product> it = products.iterator();
while(it.hasNext())
{
Product prod = it.next();
if(prod.getId_product() == id)
return prod;
}
return null;
}
public List<Product> getPizza() throws SQLException
{
Iterator<Product> it = products.iterator();
pizza = new ArrayList<Product>();
while(it.hasNext())
{
Product prod = it.next();
if(prod.getCategory() == 1)
pizza.add(prod);
}
return pizza;
}
public List<Product> getDrink() throws SQLException
{
Iterator<Product> it = products.iterator();
drink = new ArrayList<Product>();
while(it.hasNext())
{
Product prod = it.next();
if(prod.getCategory() == 2)
drink.add(prod);
}
return drink;
}
public List<Product> getOther() throws SQLException
{
Iterator<Product> it = products.iterator();
other = new ArrayList<Product>();
while(it.hasNext())
{
Product prod = it.next();
if(prod.getCategory() == 3)
other.add(prod);
}
return other;
}
public List<Product> getProducts() {
return products;
}
}
I also send a screenshot here to make code easier and faster to analize:
What happens here is that only the first button "Dodaj" (which means "add") works and add the String in outputlabel correctly. The rest of them do nothing. When I change the order, again only the first one works. Why?
You have multiple nested/cascaded <h:form>'s, that is not allowed in HTML! Either make one <h:form> and put all elements in that form, or make multiple <h:form>'s, but don't nest/cascade them!

Avoiding entity update directly on form submit

I have an entity which is showed on the screen as text in input boxes which can be modified. When i submit the form hitting save, i would like my ejb3 component to handle the data and persist or merge it using the entity manager. But for some reason, when i modify the data and hit save the data directly gets updated in the database by-pasing my ejb3, which is certainly undesirable. My code looks like the following
#Entity
#Table(name = "EMP")
public class Emp implements java.io.Serializable {
private short empno;
private Dept dept;
private String ename;
private String job;
private Short mgr;
private Date hiredate;
private BigDecimal sal;
private BigDecimal comm;
public Emp() {
}
public Emp(short empno) {
this.empno = empno;
}
public Emp(short empno, Dept dept, String ename, String job, Short mgr,
Date hiredate, BigDecimal sal, BigDecimal comm) {
this.empno = empno;
this.dept = dept;
this.ename = ename;
this.job = job;
this.mgr = mgr;
this.hiredate = hiredate;
this.sal = sal;
this.comm = comm;
}
#Id
#Column(name = "EMPNO", unique = true, nullable = false, precision = 4, scale = 0)
public short getEmpno() {
return this.empno;
}
public void setEmpno(short empno) {
this.empno = empno;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "DEPTNO")
public Dept getDept() {
return this.dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
#Column(name = "ENAME", length = 10)
#Length(max = 10)
public String getEname() {
return this.ename;
}
public void setEname(String ename) {
this.ename = ename;
}
#Column(name = "JOB", length = 9)
#Length(max = 9)
public String getJob() {
return this.job;
}
public void setJob(String job) {
this.job = job;
}
#Column(name = "MGR", precision = 4, scale = 0)
public Short getMgr() {
return this.mgr;
}
public void setMgr(Short mgr) {
this.mgr = mgr;
}
#Temporal(TemporalType.DATE)
#Column(name = "HIREDATE", length = 7)
public Date getHiredate() {
return this.hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
#Column(name = "SAL", precision = 7)
public BigDecimal getSal() {
return this.sal;
}
public void setSal(BigDecimal sal) {
this.sal = sal;
}
#Column(name = "COMM", precision = 7)
public BigDecimal getComm() {
return this.comm;
}
public void setComm(BigDecimal comm) {
this.comm = comm;
}
}
#Stateful
#Name("workflow")
#Scope(ScopeType.CONVERSATION)
public class WorkflowBean implements Workflow
{
#Logger private Log log;
#In StatusMessages statusMessages;
#PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager entityManager;
#Out(required=false)
Emp employee = new Emp();
#RequestParameter("empEmpno")
String empNo;
public void workflow()
{
log.info("workflow.workflow() action called");
statusMessages.add("workflow");
}
#End
public boolean save(){
entityManager.merge(emp);
entityManger.flush();
}
#Begin(join=true)
public boolean populateEmp(){
entityManager.setFlushMode(FlushModeType.COMMIT);
System.out.println("The Emp No. is---"+empNo);
int no = Integer.parseInt(empNo);
short emp =(short)no;
employee = entityManager.find(Emp.class, emp);
entityManager.flush();
return true;
}
public Emp getEmployee() {
return employee;
}
public void setEmployee(Emp employee) {
this.employee = employee;
}
// add additional action methods
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
#Remove
#Destroy
public void destroy() {
}
}
My view looks like
<h:form id="emp" styleClass="edit">
<rich:panel>
<f:facet name="header">Edit Emp</f:facet>
<s:decorate id="empnoField" template="layout/edit.xhtml">
<ui:define name="label">Empno</ui:define>
<h:inputText id="empno"
required="true"
value="#{workflow.employee.empno}">
</h:inputText>
</s:decorate>
<s:decorate id="commField" template="layout/edit.xhtml">
<ui:define name="label">Comm</ui:define>
<h:inputText id="comm"
value="#{workflow.employee.comm}"
size="14">
</h:inputText>
</s:decorate>
<s:decorate id="enameField" template="layout/edit.xhtml">
<ui:define name="label">Ename</ui:define>
<h:inputText id="ename"
size="10"
maxlength="10"
value="#{workflow.employee.ename}">
</h:inputText>
</s:decorate>
<s:decorate id="hiredateField" template="layout/edit.xhtml">
<ui:define name="label">Hiredate</ui:define>
<rich:calendar id="hiredate"
value="#{workflow.employee.hiredate}" datePattern="MM/dd/yyyy" />
</s:decorate>
<s:decorate id="jobField" template="layout/edit.xhtml">
<ui:define name="label">Job</ui:define>
<h:inputText id="job"
size="9"
maxlength="9"
value="#{workflow.employee.job}">
</h:inputText>
</s:decorate>
<s:decorate id="mgrField" template="layout/edit.xhtml">
<ui:define name="label">Mgr</ui:define>
<h:inputText id="mgr"
value="#{workflow.employee.mgr}">
</h:inputText>
</s:decorate>
<s:decorate id="salField" template="layout/edit.xhtml">
<ui:define name="label">Sal</ui:define>
<h:inputText id="sal"
value="#{workflow.employee.sal}"
size="14">
</h:inputText>
</s:decorate>
<s:decorate id="deptField" template="layout/edit.xhtml">
<ui:define name="label">Department</ui:define>
<h:inputText id="dname"
value="#{workflow.deptName}">
</h:inputText>
</s:decorate>
<div style="clear:both">
<span class="required">*</span>
required fields
</div>
</rich:panel>
<div class="actionButtons">
<h:commandButton id="save"
value="Save"
action="#{workflow.save}"
rendered="true"/>
</div>
</h:form>
[It was difficult to address issue in comments for your response.]
There are few things which I haven't understand & why it's done that way.
Using transient fields, it will add overhead of adding those to entity object while persisting.
Why is auto-commit causes issue & can't be implemented.
Regardless of these things, you can try
Making the entity detached with entityManager.detach(entity) or clearing the persistence context with entityManager.clear(), detaching all the underlying entities. But prior one is more favourible.
Can manage transaction manually instead of container. Use BMT where you can have control over the operations.

JPA java.lang.IllegalArgumentException: Object: [ id=XYZ ] is not a known entity type

I am faceing the following problem:
when i run my programme i get the following exceptions:
java.lang.IllegalArgumentException: Object: dviaufgabe1.MeinArtikel[
id=25 ] is not a known entity type. at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4128)
at
org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:406)
at dviaufgabe1.DVIAufgabe1.persist(DVIAufgabe1.java:78) at
dviaufgabe1.DVIAufgabe1.erstelleBasisDaten(DVIAufgabe1.java:55) at
dviaufgabe1.DVIAufgabe1.main(DVIAufgabe1.java:22)
or (for auto gen keys)
java.lang.IllegalArgumentException: Object: dviaufgabe1.MeinArtikel[
id=null ] is not a known entity type. at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4128)
at
org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:406)
at dviaufgabe1.DVIAufgabe1.persist(DVIAufgabe1.java:78) at
dviaufgabe1.DVIAufgabe1.erstelleBasisDaten(DVIAufgabe1.java:56) at
dviaufgabe1.DVIAufgabe1.main(DVIAufgabe1.java:22)
MeinArtikel.java
#Entity
public class MeinArtikel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long artikelNummer;
private String name;
private String beschreibung;
private long preis;
private long lagerbestand;
public Long getArtikelNummer() {
return artikelNummer;
}
public String getBeschreibung() {
return beschreibung;
}
public long getLagerbestand() {
return lagerbestand;
}
public String getName() {
return name;
}
public long getPreis() {
return preis;
}
public void setBeschreibung(String beschreibung) {
this.beschreibung = beschreibung;
}
public void setLagerbestand(long lagerbestand) {
this.lagerbestand = lagerbestand;
}
public void setName(String name) {
this.name = name;
}
public void setPreis(long preis) {
this.preis = preis;
}
public void setArtikelNummer(Long id) {
this.artikelNummer = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (artikelNummer != null ? artikelNummer.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the artikelNummer fields are not set
if (!(object instanceof MeinArtikel)) {
return false;
}
MeinArtikel other = (MeinArtikel) object;
if ((this.artikelNummer == null && other.artikelNummer != null) || (this.artikelNummer != null && !this.artikelNummer.equals(other.artikelNummer))) {
return false;
}
return true;
}
#Override
public String toString() {
return "dviaufgabe1.MeinArtikel[ id=" + artikelNummer + " ]";
}
main class:
public class DVIAufgabe1 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
erstelleBasisDaten();
}
public static void erstelleBasisDaten() {
MeinArtikel a1 = new MeinArtikel();
// a1.setArtikelNummer(23L);
a1.setName("Bachelor of Science - Informatik (WH)");
a1.setBeschreibung("Informatik Bachelor der Westfälischen Hochschule");
a1.setPreis(0L);
a1.setLagerbestand(100L);
MeinArtikel a2 = new MeinArtikel();
// a2.setArtikelNummer(24L);
a2.setName("Master of Science - Informatik (WH)");
a2.setBeschreibung("Informatik Master der Westfälischen Hochschule");
a2.setPreis(100L);
a2.setLagerbestand(50L);
MeinArtikel a3 = new MeinArtikel();
// a3.setArtikelNummer(25L);
a3.setName("Master of Science - Informatik (TU München)");
a3.setBeschreibung("Informatik Master der TU München");
a3.setPreis(10000L);
a3.setLagerbestand(5L);
MeinArtikel a4 = new MeinArtikel();
// a4.setArtikelNummer(26L);
a4.setName("Abitur NRW");
a4.setBeschreibung("Abitur der Klasse 13");
a4.setPreis(1000L);
a4.setLagerbestand(500L);
persist(a1);
persist(a2);
persist(a3);
persist(a4);
}
public static void persist(Object object) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("DVIAufgabe1PU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
em.persist(object);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
em.getTransaction().rollback();
} finally {
em.close();
}
}
persictence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="DVIAufgabe1PU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>dviaufgabe1. MeinArtikel</class>
<class>dviaufgabe1.MeineKategorie</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/DVIAufgabe1"/>
<property name="javax.persistence.jdbc.password" value="myuser"/>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="javax.persistence.jdbc.user" value="myuser"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>
Firstly, you should delete the space in the persistence.xml, right before "MeinArtikel" in the first tag class. Then after
<class>dviaufgabe1.MeineKategorie</class>
add this line
<exclude-unlisted-classes>false</exclude-unlisted-classes>
you are missing a space in the persistence.xml, right before "MeinArtikel"