Entity mapping issues - jpa

I am pretty new to java and data entities and I am getting the, "Exception Description: An incompatible mapping has been encountered between [class com.store.Product] and [class com.store.Cart]." error and not sure why (obviously).
My mappings are as follows:
Product.java
#Basic(optional = false)
#NotNull
#Column(name = "P_QTY")
private Integer pQty;
#Column(name = "P_PRICE")
private BigDecimal pPrice;
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "P_ID")
private String pId;
#Size(max = 10)
#Column(name = "P_NAME")
private String pName;
#Size(max = 20)
#Column(name = "P_DESC")
private String pDesc;
#OneToMany(mappedBy = "pId")
Cart.java
#Id
#Basic(optional = false)
#NotNull
#Column(name = "C_ID")
private String cId;
#Basic(optional = false)
#NotNull
#Column(name = "C_QTY")
private Integer cQty;
#Column(name = "C_PRICE")
private Double cPrice;
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 10)
#JoinColumn(name = "P_ID", referencedColumnName = "P_ID")
#ManyToOne
private String pId;
Any ideas? Like I said, I'm new to data entities and have done enough reading to confuse myself at this point so I apologize for any and all idiocy on my part.
Thanks in advance.

Related

Load tables only with some specific conditions (#Where)

What I'm trying to do is to load only promotions with promotion.enabled=1 AND PromotionType.enabled=1.
I tried to add the #Where annotation in both tables but when I set promotionType, enabled to 0 I´m getting an error.
On the other hand, I also tried to add the #WhereJoinTable clause to promotionType but I'm not getting the expected result. Any help?
The first one:
#Entity
#Table(name = "HOTEL_PROMOTION")
#Where(clause = "enabled=1")
public class Promotion implements Serializable {
private static final long serialVersionUID = 257070400893576505L;
#Id
#Column(name = "PROMOTION_ID")
private Long id;
#Column(name = "CODE")
private String code;
#Column(name = "NAME")
private String name;
#Column(name = "PRIORITY")
private Long priority;
#ManyToOne
#JoinColumn(name = "PROMOTION_TYPE_ID")
#WhereJoinTable(clause = "enabled=1")
private PromotionType promotionType;
#Column(name = "ENABLED")
private Boolean enabled;
}
The second one:
#Entity
#Table(name = "HOTEL_PROMOTION_TYPE")
public class PromotionType implements Serializable {
private static final long serialVersionUID = -8359165117733458987L;
#Id
#Column(name = "PROMOTION_TYPE_ID")
private Long id;
#Column(name = "CODE")
private String code;
#Column(name = "NAME")
private String name;
#Column(name = "STYLE")
private String style;
#Column(name = "ENABLED")
private Boolean enabled;
}

How to Map two entities of the same type in JPA

I have a case where I need to create a compatibility mapping between computer hardware parts.
The idea is to check for example if ComputerPart1(motherboard_yy) is compatible with ComputerPart1(hardrive_xx)
So I have an Entity called ComputerPart
#Entity
public class ComputerPart {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false)
private String name;
#Column(nullable = false, unique = true)
private String serialNumber;
#Column(nullable = false)
private String manufacturer;
// getter and setters
I'm not sure about the best way to do next.
Do I create an object map of computerParts with a List?
Map<ComputerPart, List<ComputerPart>>
Or Do I create another Entity Called Compatible?
The solution that I will probably chose is having a list of the same Entity Type:
#Entity
public class ComputerPart {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false)
private String name;
#Column(nullable = false, unique = true)
private String serialNumber;
#Column(nullable = false)
private String manufacturer;
#Column(nullable = false)
private String manufacturer;
// What #Annotation to put here?
//is it #ManyToMany ?
Set<ComputerPart> compatibles;
I'm not sure about the Annotation parameters.
#ManyToMany(targetEntity = ComputerPart.class, fetch = FetchType.LAZY)
#JoinTable(name = "??", joinColumns = {
#JoinColumn(name = "??", referencedColumnName = "??")},
inverseJoinColumns = {
#JoinColumn(name = "??", referencedColumnName = "??")})

Spring Boot and JpaRepository sort by distance with latitude and longitude params

I have a problem creating a query using the JpaRepository interface. I use the Pageable mechanism. How can I add sort by distance? Geographic parameters available at Event Place. (Latitude, longitude). I would like to add also the ability to limit distance by range. E.g:
"Where distance <: range".
I would like the distance to be returned in the "distance" field, which is #Transient.
EventRepository
#Repository
public interface EventRepository extends JpaRepository<Event, Long> {
public static final String GET_PAGE_QUERY = "WHERE " +
"(:searchTerm is null or e.title like '%:searchTerm%') AND " +
"((:userListId) is null or e.user.id in (:userListId)) AND " +
"((:sportTypeIdList) is null or e.sportType.id in (:sportTypeIdList)) " ;
#Query(value = "SELECT e FROM Event e " + GET_PAGE_QUERY,
countQuery = "SELECT COUNT(e) FROM Event e " + GET_PAGE_QUERY)
Page<Event> getPage(#Param("searchTerm") String searchTerm, #Param("userListId") List<Long> userListId, #Param("sportTypeIdList") List<Long> sportTypeIdList, Pageable pageable);
}
Event
#Getter
#Setter
#Entity
#Table(name = "event")
public class Event {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "event_seq")
#SequenceGenerator(name = "event_seq", sequenceName = "event_seq", allocationSize = 1)
private Long id;
#Column(name = "TITLE", length = 50, nullable = false)
#NotNull
#Size(min = 4, max = 50)
private String title;
#Column(name = "DESCRIPTION", length = 500, nullable = false)
#NotNull
#Size(min = 4, max = 500)
private String description;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
private SportType sportType;
#OneToOne(fetch = FetchType.EAGER, optional = false)
private EventPlace place;
#ManyToOne(optional = false)
private User user;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssZ")
#Column(name = "CREATE_DATE", nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#NotNull
private Date createDate = new Date();
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssZ")
#Column(name = "START_DATE", nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#NotNull
private Date startDate;
#Column(name = "STATUS", nullable = false)
#NotNull
#Enumerated(EnumType.STRING)
private EventStatus status = EventStatus.ACTIVE;
#Transient
private double distance;
}
EventPlace
#Getter
#Setter
#Entity
public class EventPlace {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "event_place_seq")
#SequenceGenerator(name = "event_place_seq", sequenceName = "event_place_seq", allocationSize = 1)
private Long id;
#Column(name = "NAME", length = 50, nullable = false)
#NotNull
#Size(min = 4, max = 50)
private String name;
#Column(name = "CITY", length = 50, nullable = false)
#NotNull
#Size(min = 4, max = 50)
private String city;
#Column(name = "STREET", length = 50, nullable = false)
#NotNull
#Size(min = 4, max = 50)
private String street;
#Column(name = "ZIP_CODE", length = 50, nullable = false)
#NotNull
#Size(min = 4, max = 50)
private String zipCode;
#Column(name = "DESCRIPTION", length = 500, nullable = false)
#NotNull
#Size(min = 4, max = 500)
private String description;
#Column(name = "LATITUDE", nullable = false)
#NotNull
private Double latitude;
#Column(name = "LONGITUDE", nullable = false)
#NotNull
private Double longitude;
}

The abstract schema type is unknown

I'm using Spring 3.2.3, JPA 2.1, JUnit 4.11. I'm trying to run a junit test and I keep getting the abstract schema type is unknown error. Here is my entity (truncated for space, it has all the getters and setters):
#Entity
#Table(name = "WEB_PROFILES")
public class TestWebProfile implements Serializable {
private static final long serialVersionUID = 1L;
#Transient
private String forward;
#Column(name = "ACCESS_FLAG")
private String accessFlag;
#Temporal(TemporalType.DATE)
#Column(name = "ACCESS_FLAG_UPD_DATE")
private Date accessFlagUpdDate;
#Column(name = "ACCESS_RESET_INTERVAL")
private BigDecimal accessResetInterval;
#Column(name = "ACCOUNT_TYPE")
private String accountType;
#Column(name = "CREATED_BY")
private String createdBy;
#Column(name = "E_MAIL")
private String eMail;
#Column(name = "FAILED_LOGIN_ATTEMPTS")
private BigDecimal failedLoginAttempts;
#Column(name = "FIRST_NAME")
private String firstName;
#Temporal(TemporalType.DATE)
#Column(name = "FROI_ACCESS_APPROVE_DENY_DATE")
private Date froiAccessApproveDenyDate;
#Column(name = "FROI_ACCESS_APPROVED_FLAG")
private String froiAccessApprovedFlag;
#Column(name = "FROI_ACCESS_REQUESTED")
private String froiAccessRequested;
#Column(name = "FROI_APPROVED_BY")
private String froiApprovedBy;
#Temporal(TemporalType.DATE)
#Column(name = "FROI_CONFIRM_EMAIL_SENT_DATE")
private Date froiConfirmEmailSentDate;
#Temporal(TemporalType.DATE)
#Column(name = "FROI_LETTER_SENT_DATE")
private Date froiLetterSentDate;
#Column(name = "LAST_LOGON_ADDR")
private String lastLogonAddr;
#Temporal(TemporalType.DATE)
#Column(name = "LAST_LOGON_DATE")
private Date lastLogonDate;
#Column(name = "LAST_NAME")
private String lastName;
#Column(name = "LAST_UPDATED_BY")
private String lastUpdatedBy;
#Column(name = "LAST_UPDATED_BY_NAME")
private String lastUpdatedByName;
#Column(name = "LAST_UPDATED_BY_SU_ID")
private BigDecimal lastUpdatedBySuId;
#Temporal(TemporalType.DATE)
#Column(name = "MAIL_SENT_DATE")
private Date mailSentDate;
#Temporal(TemporalType.DATE)
#Column(name = "MAINT_DATE")
private Date maintDate;
#Temporal(TemporalType.DATE)
#Column(name = "NEW_PIN_REQ_DATE")
private Date newPinReqDate;
#Column(name = "PASSWORD")
private String password;
#Transient
private String newPassword;
#Temporal(TemporalType.DATE)
#Column(name = "PASSWORD_UPD_DATE")
private Date passwordUpdDate;
#Column(name = "PHONE")
private String phone;
#Column(name = "PIN")
private String pin;
#Column(name = "POLICY_NUM")
private BigDecimal policyNo;
#Column(name = "PROFILE_CLASS_CODE")
private String profileClassCode;
#Temporal(TemporalType.DATE)
#Column(name = "PROFILE_REQ_DATE")
private Date profileReqDate;
#Temporal(TemporalType.DATE)
#Column(name = "PROFILE_UPDATE_DATE")
private Date profileUpdateDate;
#Column(name = "REMOTE_ADDR")
private String remoteAddr;
#Column(name = "SESSIONID")
private String sessionid;
#Column(name = "SUBSCRIBER_FLAG")
private String subscriberFlag;
#Column(name = "USER_ID")
private BigDecimal userId;
#Id
#Column(name = "USER_NO")
private BigDecimal userNo;
#Column(name = "USERNAME")
private String username;
My JUnit test:
#Test
public void testGetWebProfileByUsername() {
TestWebProfile wp = sso.getWebProfile("MARLENE");
System.out.println("name :" + wp.getFirstName());
System.out.println("last name :" + wp.getLastName());
}
My DAO implementation:
#Override
public TestWebProfile getWebProfile(String username) {
String sqlString = "select w from TestWebProfile w where w.username =:username";
return (TestWebProfile) getEntityManager()
.createQuery(sqlString, TestWebProfile.class)
.setParameter("username", username).getSingleResult();
}
After Googling for the past hour, the only culprit I found that seem to make sense was not having the #Id and #Column annotations, but I have those on the userNo variable. Any help that can be provided would be greatly appreciated!
Have a look at this. It gives some suggesstion for the same case http://java.dzone.com/tips/the-nasty-jpa-unknown-abstract
If you are using Java SE you have to add the fully qualified name of your entity class in persistence.xml, like so
<persistence-unit ...>
<class>your.custom.package.TestWebProfile</class>
</persistence-unit>
Omitting the package part may lead to your error.
Try adding inside your persistence-unit tag as follows:
<exclude-unlisted-classes>false</exclude-unlisted-classes>
For some reason in my case although I was listing all the classes inside my persistence unit using fully qualified names, eclipseLink didn't recognize them. Once added that line, it just works.
I was using:
Java SE 8
Maven Project
EclipseLink (Local not an application server)
Netbeans

Insert object with composite primary key

I need help with this. With code is more clear, this is my function to persist:
public String finalizarCompra() {
Pedido pedido = new Pedido();
pedido.setEstado("almacen");
pedido.setFechaVenta(new Date());
pedido.setIdUsuario(loginBean.getUsuario());
Producto p;
Integer i;
DetPedido detPedido;
List<DetPedido> lista = new ArrayList<>();
for (Map.Entry e : productos.entrySet()) {
detPedido = new DetPedido();
p = (Producto) e.getKey();
i = (Integer) e.getValue();
detPedido.setProducto(p);
detPedido.setCantidad(i);
detPedido.setPrecioUnidad(p.getPrecioUnidad());
detPedido.setPedido(pedido);
lista.add(detPedido);
detPedidoBean.insert(detPedido);
}
pedido.setDetPedidoCollection(lista);
pedidoBean.insert(pedido);
return "";
}
This is my Pedido Entity:
#Entity
public class Pedido implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "ID_PEDIDO")
private Integer idPedido;
#Basic(optional = false)
#NotNull
#Column(name = "FECHA_VENTA")
#Temporal(TemporalType.TIMESTAMP)
private Date fechaVenta;
#Column(name = "FECHA_ENVIO")
#Temporal(TemporalType.TIMESTAMP)
private Date fechaEnvio;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 50)
#Column(name = "ESTADO")
private String estado;
#JoinColumn(name = "ID_USUARIO", referencedColumnName = "ID_USUARIO")
#ManyToOne(optional = false)
private Usuario idUsuario;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "pedido")
private Collection<DetPedido> detPedidoCollection;
// Getters and Setters //
This is my DetPedido Entity:
#Entity
public class DetPedido implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected DetPedidoPK detPedidoPK;
#Basic(optional = false)
#NotNull
#Column(name = "CANTIDAD")
private Integer cantidad;
#Basic(optional = false)
#NotNull
#Column(name = "PRECIO_UNIDAD")
private Double precioUnidad;
#JoinColumn(name = "ID_PRODUCTO", referencedColumnName = "ID_PRODUCTO", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Producto producto;
#JoinColumn(name = "ID_PEDIDO", referencedColumnName = "ID_PEDIDO", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Pedido pedido;
// Getters and Setters //
And this is my DetPedidoPK:
#Embeddable
public class DetPedidoPK implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "ID_PEDIDO")
private Integer idPedido;
#Basic(optional = false)
#NotNull
#Column(name = "ID_PRODUCTO")
private Integer idProducto;
// Getters and Setters //
The Entities ara generated automatically from the Database, also DetPedidoPK, and now I don't know how to save a Pedido. I tried with the code above, but it doesn't work.
Can anybody help me?
Greetings.
If you are using JPA 1.0 and this entity model, then you will need to persist and flush both Producto and Pedido instances to have their IDs assigned before you can persist the DetPedido instance that will reference them. Once that is done, you will need to manually set the id values in DetPedido's DetPedidoPK instance so that they match the referenced Producto and DetPedido key values. You cannot insert DetPedido without the DetPedidoPK values having been set.
JPA 2.0 supports derived IDs, which allows marking the relationship as either #ID or #MapsId, indicating that the ID values should be pulled from the joincolumn associated to the relationship. In this case, it would become:
#ManyToOne(optional = false)
#MapsId("idProducto")
private Producto producto;
#ManyToOne(optional = false)
#MapsId("idPedido")
private Pedido pedido;
If you wanted, you could do away with the embeddable within DetPedido and just mark the relationships as the #Id, and because it is composite you would use the DetPedidoPK as the PK class.