i have Entity mapped to table TABLE1 with columns COLUMN1 and COLUMN2
i have class ResViewer
public class ResViewer() {
private boolean flag;
private int property;
...selectors
}
i have entity class
#Entity
#Table(name="TABLE1")
public class Table1() {
#Id
private long id;
private ResViewer res1;
private ResViewer res2;
...selectors
}
How can i map field flag of classes res1 and res2 to columnds COLUMN1 and COLUMN2?
Your ResViewer needs to be annotated with #Embeddable, and the fields res1 and res2 must be annotated with #Embedded, and with #AttributeOverrides, as demonstrated in the javadoc of #Embedded.
Related
I have two tables A and B. There are two columns in table A, col1 and col2(both the columns are primary key, i.e. composite with col1 and col2). There is one column in table B, to which both the columns from table A are pointing to, i.e. col1 and col2 are foreign keys with relation to column in table B.
How can I implement the JPA entity for table A?
Thank you
Well you can achieve that by following code:
#Embeddable
public class AID {
public int xID;
public int yId;
}
#Entity
public class A {
#EmbeddedId
public AID id;
#OneToMany(mappedBy="A")
public Collection<B> b;
}
#Entity
public class Meeting {
#ID
#GeneratedValue
public Long id;
#MapsId("aID")
#JoinColumns({
#JoinColumn(name="xID", referencedColumnName="xID"),
#JoinColumn(name="yId", referencedColumnName="yId")
})
#ManyToOne
public A a;
}
I'm trying to implement a query like this in JPA:
SELECT
ta.field_aggr_1,
ta.field_aggr_2,
MIN(tb.date_inv) AS min_date_inv,
MAX(tb.date_inv) AS max_date_inv
FROM table_a ta
INNER JOIN table_b tb ON ta.idB = tb.id
GROUP BY
ta.field_aggr_1,
ta.field_aggr_2
The key point is the MIN and MAX functions that apply in one column of a joined table.
I've created the entities:
#Entity
#Table(name="table_a")
public class EntityA extends Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
#Column(name="field_aggr_1")
private String field_aggr_1;
#Column(name="field_aggr_2")
private String field_aggr_2;
#ManyToOne
#JoinColumn(name="idB")
private EntityB entityB;
// Getters & Setters & HashCode & equals & toString
}
#Entity
#Table(name="table_b")
public class EntityB extends Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
#Column(name="date_inv")
private String date_inv;
// Getters & Setters & HashCode & equals & toString
}
And in the service I want to create query:
EntityManager em = ...;
Root<EntityA> root = criteriaQuery.from(EntityA.class);
EntityType<EntityA> type = this.em.getMetamodel().entity(EntityA.class);
Join<EntityA, EntityB> join = root.join(type.getDeclaredSingularAttribute("entityB", EntityB.class));
List<Selection<?>> fields = new ArrayList<Selection<?>>();
// grouping fields
fields.add(root.<EntityA>get("field_aggr_1"));
fields.add(root.<EntityA>get("field_aggr_2"));
I've managed to include fields from the joined table,
fields.add(join.<EntityB>get("date_inv"));
BUT I haven't succeed in implement the min aggregation.
Thanks in advance for your answers!
I have managed to solve the question. First, I needed to have one more "root" and one more "entityType" for the joined entity:
Root<EntityB> rootB = criteriaQuery.from(EntityB.class);
EntityType<EntityB> typeB = this.em.getMetamodel().entity(EntityB.class);
With these, now I can do what I needed:
fields.add(builder.least(rootB.get(typeB.getDeclaredSingularAttribute("date_inv", String.class))));
fields.add(builder.greatest(rootB.get(typeB.getDeclaredSingularAttribute("date_inv", String.class))));
Hope that it helps someone!
i have an existing table for TransactionLogs which is either links to a External or to a InternalType. the id's corresponding to the cash adjustment & game transaction are stored in a single column called transaction id and a separate column called type indicates which table is it linked to
Because of the nature of the existing table, i mapped it in a single table inheritance:
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.INTEGER)
public class TransLog implements Serializable {
#Id
#GeneratedValue
private Long id;
private Integer type;
// getters and setters
}
#Entity
public class InternalAdjustmentTransLog extends TransLog {
#ManyToOne
#JoinColumn(name = "TransID", nullable = false)
private InternalAdjustmentRecord internalAdjustmentRecord;
// getters and setters
}
#Entity
public class ExternalTransLog extends TransLog {
#ManyToOne
#JoinColumn(name = "TransID", nullable = false)
private ExternalAdjustmentRecord externalAdjustmentRecord;
}
each of these two subclasses has their subclasses with defined descriminator values..
With the setup given above, there are instances that i need to get a unified data of both
internal and external records. What is the best way to accomplish this? at first i thought it would be enough to use the TransLog as the root class for the query (i'm using jpa criteria). however, i need to get TransId (which are defined in the subclasses and points to 2 different objects of no relationship).
Thanks.
You can make abstract method in TransLog that returns what you need and implement it in both subclasses.
I have 2 entities for legacy db with composite keys, one of them has a composite key with #EmbeddedId annotation.
// first entity
#Entity
public class Product {
#Id
private Integer productId;
// lookup table contains code-description pairs
#OneToOne
private ProductDefects defects;
//getters and setters and other code omitted
}
// lookup entity
#Entity
public class ProductDefects {
#EmbededId
private ProductDefectsPK id;
//getters and setters and other code omitted
}
//composite key
#Embedable
public class ProductDefectsPk{
private Integer realId;
private String category;
}
How should I define the #OneToOne relation to join as in the following example:
select p.Id, pd.description
from Product p
inner join p.defects pd
I figure out that #MapsId annotation helps in my case http://download.oracle.com/javaee/6/api/javax/persistence/MapsId.html
I have 2 entities:
#Entity
public class Elements implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Owner owner;
}
#Entity
public class Owner implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(fetch=FetchType.LAZY)
List<Elements> elements;
}
Suppose I want to fetch all elemets bellonging to the owner from Elements Table and therfore I use:
TypedQuery query=em.createQuery("SELECT elem FROM Elements elem WHERE
elem.owner:=elemOwner", Elements.class);
query.setParameter("elemOwner", ownerObjectFetchFromDataBase);
List<TrendUsers> userList=query.getResultList();
But I get the following error:
Comparisons between 'BLOB' and 'BLOB' are not supported. Types must be comparable. String types must also have matching collation.
If collation does not match, a possible solution is to cast operands to force them to the default collation...
Is there any way I can Select from Elements Table and in the WHERE clause use object (and not just String,int...)?
(p.s I also tried the query below and it didn't work:
TypedQuery query=em.createQuery("SELECT elem FROM Elements elem WHERE elem.owner.id:=elemOwner", Elements.class);
query.setParameter("elemOwner", ownerObjectFetchFromDataBase.id);
List userList=query.getResultList();
)
Thanks
You need to mark the Owner als a ManyToOne.
#Entity public class Elements implements Serializable {
...snip ...
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="OWNER_ID")
private Owner owner;
}
#Entity public class Owner implements Serializable {
.. snip ...
#OneToMany(fetch=FetchType.LAZY, mappedBy="owner")
List<Elements> elements;
}
Right now you try to store the serialized owner in Blob. Thats not what you want ;-)
enjoy
Edit: included fix by xatavt